我的City结构是这样的:
City
type City struct { ID int Name string Regions []Region }
而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}}
引用的文档text/template,该{{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.
这意味着您可以将一个可选数据传递给模板执行,而不是更多。如果要传递多个值,则必须将它们包装为传递的某个单个值。
因此,我们应该将这些数据包装到struct或map中。但是我们不能在模板中编写Go代码。我们可能要做的是注册一个函数,将这些数据传递给该函数,该函数可以进行“打包”并返回单个值,现在我们可以将其传递给{{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()函数以生成单个值:
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}]