我的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}}
答案 0 :(得分:1)
引自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.
这意味着您可以将一个可选数据传递给模板执行,而不是更多。如果要传递多个值,则必须将它们包装为传递的单个值。有关详细信息,请参阅How to pass multiple data to Go template?
因此我们应该将这些数据包装到结构或地图中。但我们无法在模板中编写Go代码。我们可以做的是注册一个我们传递这些数据的函数,该函数可以执行" packing"并返回一个值,现在我们可以传递给{{template}}
动作。
这是一个示例包装器,它只是将这些包装到地图中:
func Wrap(shops []Destination, cityName, regionName string) map[string]interface{} {
return map[string]interface{}{
"Shops": shops,
"CityName": cityName,
"RegionName": regionName,
}
}
可以使用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)
}
输出(在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}]
答案 1 :(得分:0)
我猜CityWithSomeData
是一个切片,如果是这样的尝试:
type viewModel struct {
List []City
}
然后,在你的模板中:
{{range .List}}
{{$city:=.Name}}
{{range .Regions}}
{{$region:=.Name}}
{{template "data" .Shops $city $region}}
{{end}}
{{end}}