5 struct loops go slice go-templates
我的City结构是这样的:
type City struct {
ID int
Name string
Regions []Region
}
Run Code Online (Sandbox Code Playgroud)
而Region结构是:
type Region struct {
ID int
Name string
Shops []Destination
Masters []Master
EducationCenters []Destination
}
Run Code Online (Sandbox Code Playgroud)
主要是我尝试这样做:
tpl.ExecuteTemplate(resWriter,"cities.gohtml",CityWithSomeData)
Run Code Online (Sandbox Code Playgroud)
是否可以在模板内部做这样的事情?
{{range .}}
{{$city:=.Name}}
{{range .Regions}}
{{$region:=.Name}}
{{template "data" .Shops $city $region}}
{{end}}
{{end}}
Run Code Online (Sandbox Code Playgroud)
引用 doc of 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.
Run Code Online (Sandbox Code Playgroud)
这意味着您可以将一个可选数据传递给模板执行,而不是更多。如果你想传递多个值,你必须将它们包装成你传递的单个值。有关详细信息,请参阅如何将多个数据传递给 Go 模板?
所以我们应该把这些数据包装成一个结构体或一个映射。但是我们不能在模板中编写 Go 代码。我们可以做的是注册一个函数,我们将这些数据传递给该函数,该函数可以执行“打包”并返回一个值,现在我们可以将其传递给{{template}}操作。
这是一个示例包装器,它只是将它们打包到地图中:
func Wrap(shops []Destination, cityName, regionName string) map[string]interface{} {
return map[string]interface{}{
"Shops": shops,
"CityName": cityName,
"RegionName": regionName,
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用该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}}`
Run Code Online (Sandbox Code Playgroud)
这是一个可运行的示例,显示了这些操作:
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)
}
Run Code Online (Sandbox Code Playgroud)
输出(在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}]
Run Code Online (Sandbox Code Playgroud)