英文:
Go html template access struct fields inside range
问题
给定以下结构体,我想在遍历field1
数据时访问field2
。我该如何做?
var MyPageData struct {
field1 []Foo
field2 map[string]Bar
}
我尝试了以下代码,在处理函数中:
err := myPageTemplate.Execute(w, MyPageData{field1: field1Slice, field2: myMapData})
模板代码如下:
{{ range $index, $fooInstance := .field1}}
<tr>
<td>{{$fooInstance.Name}}</td> <!-- 这里打印了 Name 的值 -->
<td>{{ index .$field2 "myKey".Name }}</td>
我如何访问上面的field2
并指定一个键值来检索Bar
实例?
更新 添加了Foo
和Bar
结构体的定义:
type Foo2 struct {
Name string
Id int
}
type Foo struct {
Name string
Element Foo2
}
type Bar struct {
Name string
}
英文:
Given below struct, I want to access field2
while iterating over field1
data in html. How do I do this?
var MyPageData struct {
field1 []Foo
field2 map[string]Bar
}
I tried: Inside Handler function:
err := myPageTemplate.Execute(w,MyPageData{ field1: field1Slice, field2 : myMapData})
Template:
{{ range $index, $fooInstance := .field1}}
<tr>
<td>{{$fooInstance.Name}}</td> //This prints the Name value
<td>{{ index .$field2 "myKey".Name }}</td>
How do I access field2
above and specify a key value to retrieve Bar
instance?
UPDATE Adding Foo and Bar structs
<!-- language : Go -->
type Foo2 struct {
Name string
Id int
}
type Foo struct {
Name string
element Foo2
}
type Bar struct {
Name string
}
答案1
得分: 4
无论管道的值是什么(在模板中用点号 .
表示),你可以使用 $
来引用传递给 Template.Execute()
的数据值。{{range}}
动作遍历元素并将管道(.
)设置为当前项,因此 .
总是表示当前项,$
绝对指的是传递给 Template.Execute()
的“顶层”数据。
这在 text/template
中有记录:
> 当执行开始时,$ 被设置为传递给 Execute 的数据参数,也就是 dot 的初始值。
还要注意,你必须导出结构字段以在模板中使用。所以将你的 MyPageData
类型改为:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
还要注意,你可以使用 .
运算符简单地访问映射元素。所以你可以在 {{range}}
动作中像这样访问与 "myKey"
键关联的 Field2
映射的值:
{{$.Field2.myKey}}
看看这个简单的例子:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
type Foo struct {
Name string
}
type Bar struct {
Name string
}
func main() {
t := template.Must(template.New("").Parse(templ))
mpd := MyPageData{
Field1: []Foo{{"First"}, {"Second"}},
Field2: map[string]Bar{"myKey": {"MyValue"}},
}
t.Execute(os.Stdout, mpd)
}
const templ = `{{range $idx, $foo := .Field1}}{{$.Field2.myKey}} {{$idx}} - {{$foo.Name}}
{{end}}`
输出结果(在 Go Playground 上尝试):
{MyValue} 0 - First
{MyValue} 1 - Second
还要注意,在 {{range}}
中,你可以使用 {{.Name}}
来代替 $foo.Name
,因为点号 .
表示 $foo
,即当前项。
如果你想使用动态键从 Field2
中查找一个值,你确实需要使用 {{index}}
动作。例如,如果你想要与键 $foo.Name
关联的值:
{{index $.Field2 $foo.Name}}
或简写为:
{{index $.Field2 .Name}}
此外,如果与键关联的值是一个结构体,你只需要这个结构体的一个字段,比如 Id
,你可以使用括号:
{{(index $.Field2 .Name).Id}}
英文:
No matter what the value of the pipeline is (which is denoted by the dot .
in the template), you can use the $
to refer to the data value you passed to Template.Execute()
. The {{range}}
action iterates over the elements and it sets the pipeline (.
) to the current item, so .
always denotes the current item, $
is absolutely refers to the "top level" data passed to Template.Execute()
.
This is documented in text/template
:
> When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.
Also note that you have to export struct fields to be available in templates. So change your MyPageData
type to:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
Also note that you can simply access map elements using the .
operator. So you can access the value of the Field2
map associated with the "myKey"
key like this, inside the {{range}}
action too:
{{$.Field2.myKey}}
See this simple example:
type MyPageData struct {
Field1 []Foo
Field2 map[string]Bar
}
type Foo struct {
Name string
}
type Bar struct {
Name string
}
func main() {
t := template.Must(template.New("").Parse(templ))
mpd := MyPageData{
Field1: []Foo{{"First"}, {"Second"}},
Field2: map[string]Bar{"myKey": {"MyValue"}},
}
t.Execute(os.Stdout, mpd)
}
const templ = `{{range $idx, $foo := .Field1}}{{$.Field2.myKey}} {{$idx}} - {{$foo.Name}}
{{end}}`
Output (try it on the Go Playground):
{MyValue} 0 - First
{MyValue} 1 - Second
Also note that insdie the {{range}}
instead of $foo.Name
you can simply use {{.Name}}
as the dot .
denotes $foo
, the current item.
If you want to lookup a value from Field2
with a dynamic key, you do need to use the {{index}}
action. For example if you want the value associated with the key being $foo.Name
:
{{index $.Field2 $foo.Name}}
Or short:
{{index $.Field2 .Name}}
And going forward, if the value associated with the key is a struct for example, and you only need a field of this struct, let's say Id
, you can use parenthesis:
{{(index $.Field2 .Name).Id}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论