Templates Go模板:是否可以嵌套范围?
这个看起来很简单,但它让我发疯 如何在golang模板的嵌套范围内引用范围中较高的结构元素 例如:Templates Go模板:是否可以嵌套范围?,templates,go,Templates,Go,这个看起来很简单,但它让我发疯 如何在golang模板的嵌套范围内引用范围中较高的结构元素 例如: type Foo struct { Id string Name string } type Bar struct { Id string Name string } var foos []Foo var bars []Bar // logic to populate both foos and bars 在模板中: {{range .foos}} <div>
type Foo struct {
Id string
Name string
}
type Bar struct {
Id string
Name string
}
var foos []Foo
var bars []Bar
// logic to populate both foos and bars
在模板中:
{{range .foos}}
<div>Foo {{.Name}}</div>
<div>
{{range ..bars}}
<div>Bar {{.Name}} <input type="text" name="ids_{{..Id}}_{{.Id}}" /></div>
{{end}}
</div>
{{end}}
{{range.foos}
Foo{{.Name}
{{range..bar}
条{{.Name}
{{end}
{{end}
显然…酒吧和…我不工作,但希望我的意图是明确的。我希望遍历Foo和Bar的所有组合,并生成一个表单元素,其名称由Foo的Id和Bar的Id生成
问题在于,似乎不可能:
文本/模板
包。如果您使用的是html/template
,语法是相同的(它们告诉您阅读text/template;)。下面是一个完整的工作解决方案,可以解决您可能想要做的事情
Go文件:
package main
import (
"bytes"
"io/ioutil"
"os"
"strconv"
"text/template"
)
type Foo struct {
Id string
Name string
}
type Bar struct {
Id string
Name string
}
var foos []Foo
var bars []Bar
func main() {
foos = make([]Foo, 10)
bars = make([]Bar, 10)
for i := 0; i < 10; i++ {
foos[i] = Foo{strconv.Itoa(i), strconv.Itoa(i)} // just random strings
bars[i] = Bar{strconv.Itoa(10 * i), strconv.Itoa(10 * i)}
}
tmpl, err := ioutil.ReadFile("so.tmpl")
if err != nil {
panic(err)
}
buffer := bytes.NewBuffer(make([]byte, 0, len(tmpl)))
output := template.Must(template.New("FUBAR").Parse(string(tmpl)))
output.Execute(buffer, struct {
FooSlice []Foo
BarSlice []Bar
}{
FooSlice: foos,
BarSlice: bars,
})
outfile, err := os.Create("output.html")
if err != nil {
panic(err)
}
defer outfile.Close()
outfile.Write(buffer.Bytes())
}
这个故事的两个寓意是a) 明智地使用模板中的变量,它们是有益的
b) 模板中的范围也可以设置变量,您不需要仅依赖
$
或
{{ $foos := .FooSlice }}
{{ $bars := .BarSlice }}
{{range $foo := $foos }}
<div>Foo {{$foo.Name}}</div>
<div>
{{range $bar := $bars}}
<div>Bar {{$bar.Name}} <input type="text" name="ids_{{$foo.Id}}_{{$bar.Id}}" /></div>
{{end}}
</div>
{{end}}