英文:
Go Templates: two or more slices ranges
问题
下面是翻译好的内容:
下面的代码可以完美地输出HomeTemplate中的一个切片。
main.go
type Item struct {
    Id   int
    Name string
    Type string
}
var tmpl = template.Must(template.ParseGlob("tmpl/*"))
func Index(w http.ResponseWriter, r *http.Request) {
    db := database.DbConn()
    selDB, err := product.ByID()
    if err != nil {
        panic(err.Error())
    }
    i := Item{}
    resItems := []Item{}
    for selDB.Next() {
        var id int
        var product_name, product_type string
        err = selDB.Scan(&id, &product_name, &product_type)
        if err != nil {
            panic(err.Error())
        }
        i.Id = id
        i.Name = product_name
        i.Type = product_type
        resItems = append(resItems, i)
    }
    tmpl.ExecuteTemplate(w, "HomeTemplate", resItems)
    // Close database connection
    defer db.Close()
}
在模板中,下面的代码可以正常工作:
{{ range . }}
    {{ .Name }}<br />
{{ end }}
为什么像下面这样的代码不起作用?
{{ range .resItems }}
    {{ .Name }}<br />
{{ end }}
如果我想输出两个或更多的切片,我需要做什么或者改变什么?
谢谢。
英文:
The next code works perfect for output one slice inside the HomeTemplate.
main.go
type Item struct {
	Id          int
	Name string
	Type      string
}
var tmpl = template.Must(template.ParseGlob("tmpl/*"))
func Index(w http.ResponseWriter, r *http.Request) {
	db := database.DbConn()
	selDB, err := product.ByID()
	if err != nil {
		panic(err.Error())
	}
	i := Item{}
	resItems := []Item{}
	for selDB.Next() {
		var id int
		var product_name, product_type string
		err = selDB.Scan(&id, &product_name, &product_type)
		if err != nil {
			panic(err.Error())
		}
		i.Id = id
		i.Name = product_name
		i.Type = product_type
		resItems = append(resItems, i)
	}
	tmpl.ExecuteTemplate(w, "HomeTemplate", resItems)
	// Close database connection
	defer db.Close()
}
In the template forks fine the next code:
{{ range . }}
    {{ .Name }}<br />
{{ end }}
Why something like this does not work?
{{ range .resItems }}
    {{ .Name }}<br />
{{ end }}
What if I want output two or more slices, what I need to do or change?
Thank you
答案1
得分: 0
第一个问题,为什么rang .resItems不起作用?
在模板中,.表示当前项,类似于Java中的this。如果.在某个方向上,比如range,它表示来自range操作的项。如果不是这样,它表示你从ExecuteTemplate()方法传递的项,比如在ExecuteTemplate(w, "HomeTemplate", resItems)中,.表示resItems。所以你不能使用.resItems,因为它表示resItems有一个名为resItems的值。
第二个问题,如果你有更多的切片要传递给模板,你可以将它们全部添加到一个映射中,像这样:
t := template.New("test")
t, _ = t.Parse(`
test range 
{{range .first}} {{.}} {{end}}
{{range .second}} {{.}} {{end}}
`)
var res = make(map[string]interface{})
aa := []string{"first", "second"}
bb := []string{"123", "456"}
res["first"] = aa
res["second"] = bb
t.Execute(os.Stdout, res)
输出结果为:
test range
 first  second
 123  456
我有两个数组aa和bb,将它们添加到一个映射中,然后将其传递给模板。在模板中,.表示该映射,.first获取了数组aa,.second获取了数组bb。
希望这能帮到你...
英文:
first question, why rang .resItems doesn't work.
In template, . means current item. like this in java.
if . in some direction like range, it means the item from range operation.
if not, it means the item you passed form ExecuteTemplate() method. like in ExecuteTemplate(w, "HomeTemplate", resItems), . means resItems. so you can not use .resItems because it means resItems have a value called resItems.
second, if you have more slices to pass to template, you can add all of them to a map, like this:
t := template.New("test")
t, _ = t.Parse(`
test range 
{{range .first}} {{.}} {{end}}
{{range .second}} {{.}} {{end}}
`)
var res = make(map[string]interface{})
aa := []string{"first", "second"}
bb := []string{"123", "456"}
res["first"] = aa
res["second"] = bb
t.Execute(os.Stdout, res)
// output
test range
 first  second
 123  456
I have two array aa and bb, and add them to a map then pass it to the template. In template, . means the map, and .first got the array aa. and so as bb.
Hope this can help you...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论