如何通过模板中的变量访问对象字段?
How do I access object field by variable in template?
我有一个嵌套循环:
{{$columns := .columns}}
{{range $dx := .dataList}}
{{range $c := $columns}}
{{index $dx $c}}
{{end}}
{{end}}
dataList是orm模型数组。使用 ID, Title
fields ,然后 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]
要访问由名称给定的结构的字段值,您需要 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"
函数中省略了错误检查。如果给定的字段名称无效,您可以将其改进为 return nil
,或者 return 由模板引擎处理的错误(在这种情况下,模板执行将因错误而中止你return).
我有一个嵌套循环:
{{$columns := .columns}}
{{range $dx := .dataList}}
{{range $c := $columns}}
{{index $dx $c}}
{{end}}
{{end}}
dataList是orm模型数组。使用 ID, Title
fields ,然后 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]
要访问由名称给定的结构的字段值,您需要 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"
函数中省略了错误检查。如果给定的字段名称无效,您可以将其改进为 return nil
,或者 return 由模板引擎处理的错误(在这种情况下,模板执行将因错误而中止你return).