我有一个嵌套循环:
{{$columns := .columns}}
{{range $dx := .dataList}}
{{range $c := $columns}}
{{index $dx $c}}
{{end}}
{{end}}
dataList是orm模型数组。对于ID, Title
字段,columns
[]string
变量包含所有orm模型字段名称,如ID, Title
。
type AdFile struct {
ID uint `gorm:"primary_key"`
Title string
}
我尝试使用{{(index .listData 0).Title}}
并且有效。
但是,如果我想访问$dx.Title
,$dx.ID
.... Title
,ID
作为变量,但它不起作用。我试过$dx[$c]
。
可以轻松地用Python实现同样的目标
for i in list_data
tr
for p in columns
td=i[p]
答案 0 :(得分:2)
要访问由其名称指定的结构的字段值,您需要reflect
包中的帮助。可以这样做:
v := AdFile{ID:1, Title: "T1"} // A struct value
name := "ID" // field name
fieldValue := reflect.ValueOf(v).FieldByName(name).Interface()
由于这是Go代码,因此您无法将其嵌入到模板中。但是您可以使用Template.Funcs()
方法注册自定义函数,该方法可以从模板中调用。
所以让我们这样做:将此功能包装到一个函数中,并使用名称"Field"
注册它,以便我们可以从我们的模板中调用它。
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"Field": func(v interface{}, name string) interface{} {
return reflect.ValueOf(v).FieldByName(name).Interface()
},
}).Parse(templ))
m := map[string]interface{}{
"columns": []string{"ID", "Title"},
"dataList": []AdFile{
{ID: 1, Title: "Title1"},
{ID: 2, Title: "Title2"},
},
}
if err := t.Execute(os.Stdout, m); err != nil {
panic(err)
}
}
const templ = `{{$columns := .columns}}
{{range $dx := .dataList}}
{{range $c := $columns}}
{{- Field $dx $c }}
{{end}}
{{end}}`
上述应用的输出(在Go Playground上尝试):
1
Title1
2
Title2
注意:注册的"Field"
函数中省略了错误检查。如果给定的字段名称无效,您可以改进它以返回nil
,或者返回由模板引擎处理的错误(在这种情况下,模板执行将因您返回的错误而中止)。