如何在模板之间传递多个值?

问题描述 投票:2回答:2

我的City结构是这样的:

type City struct {
    ID      int
    Name    string
    Regions []Region
}  

[Region结构是:

type Region struct {
    ID               int
    Name             string
    Shops            []Destination
    Masters          []Master
    EducationCenters []Destination
}

主要是我尝试这样做:

tpl.ExecuteTemplate(resWriter,"cities.gohtml",CityWithSomeData)

是否可以在模板内部执行类似的操作?

{{range .}}
        {{$city:=.Name}}
            {{range .Regions}}
                      {{$region:=.Name}}
                      {{template "data" .Shops $city $region}}
            {{end}}
{{end}}
loops go struct slice go-templates
2个回答
2
投票

引用text/template的文档,text/template操作的语法:

{{template}}

这意味着您可以将一个可选数据传递给模板执行,不能传递更多。如果要传递多个值,则必须将它们包装为传递的某个单个值。有关详细信息,请参见{{template "name"}} The template with the specified name is executed with nil data. {{template "name" pipeline}} The template with the specified name is executed with dot set to the value of the pipeline.

因此,我们应该将这些数据包装到结构或映射中。但是我们不能在模板中编写Go代码。我们可以做的是注册一个函数,将这些数据传递给该函数,该函数可以进行“打包”并返回单个值,现在我们可以将其传递给How to pass multiple data to Go template?操作。

这里是一个示例包装程序,将这些程序简单地包装到地图中:

{{template}}

可以使用func Wrap(shops []Destination, cityName, regionName string) map[string]interface{} { return map[string]interface{}{ "Shops": shops, "CityName": cityName, "RegionName": regionName, } } 方法注册自定义功能,并且不要忘记在解析模板文本之前必须执行此操作。

这里是一个经过修改的模板,它调用此Template.Funcs()函数以产生单个值:

Template.Funcs()

这是一个可运行的示例,显示了它们的作用:

Wrap()

输出(在const src = ` {{define "data"}} City: {{.CityName}}, Region: {{.RegionName}}, Shops: {{.Shops}} {{end}} {{- range . -}} {{$city:=.Name}} {{- range .Regions -}} {{$region:=.Name}} {{- template "data" (Wrap .Shops $city $region) -}} {{end}} {{- end}}` 上尝试):

t := template.Must(template.New("cities.gohtml").Funcs(template.FuncMap{
    "Wrap": Wrap,
}).Parse(src))
CityWithSomeData := []City{
    {
        Name: "CityA",
        Regions: []Region{
            {Name: "CA-RA", Shops: []Destination{{"CA-RA-SA"}, {"CA-RA-SB"}}},
            {Name: "CA-RB", Shops: []Destination{{"CA-RB-SA"}, {"CA-RB-SB"}}},
        },
    },
    {
        Name: "CityB",
        Regions: []Region{
            {Name: "CB-RA", Shops: []Destination{{"CB-RA-SA"}, {"CB-RA-SB"}}},
            {Name: "CB-RB", Shops: []Destination{{"CB-RB-SA"}, {"CB-RB-SB"}}},
        },
    },
}
if err := t.ExecuteTemplate(os.Stdout, "cities.gohtml", CityWithSomeData); err != nil {
    panic(err)
}

0
投票

我想Go Playground是一个切片,如果是这样的话,尝试一下:

City: CityA, Region: CA-RA, Shops: [{CA-RA-SA} {CA-RA-SB}]

City: CityA, Region: CA-RB, Shops: [{CA-RB-SA} {CA-RB-SB}]

City: CityB, Region: CB-RA, Shops: [{CB-RA-SA} {CB-RA-SB}]

City: CityB, Region: CB-RB, Shops: [{CB-RB-SA} {CB-RB-SB}]

然后,在您的模板中:

CityWithSomeData
© www.soinside.com 2019 - 2024. All rights reserved.