如何将多个数据传递给 Go 模板?

How to pass multiple data to Go template?

我想将两个数据对象传递给 Go Template。一个是 MongoDB 查询结果,另一个是整数数组。

MongoDB 查询:-

var results []User
sess, db := GetDatabase()
defer sess.Close()
c := db.C("user")
err := c.Find(nil).All(&results)

我想通过以下代码发送 'result' 和一个 int 数组

GetTemplate("list").Execute(w,???????)

如果只有数据库结果,我们可以将其用作

GetTemplate("list").Execute(w,results)

在模板中我们可以访问它 {{.Name}} 等(其中 Name 是 []User 的结构字段)

请告诉我如何传递这些数据以及如何在模板中访问它们。

您只能传递一个值,但该值可以是多个值的组合值,例如结构、映射或切片。因此,只需将用于模板的多个数据包装在 structmap.

带有 struct 的示例:

type Data struct {
    Results []User // Must be exported!
    Other   []int  // Must be exported!
}

data := &Data{results, []int{1, 2, 3}}
if err := GetTemplate("list").Execute(w, data); err != nil {
    // Handle error
}

另请注意,不需要新的命名类型,您也可以使用匿名结构文字,如下所示:

data := struct {
    Results []User // Must be exported!
    Other   []int  // Must be exported!
}{results, []int{1, 2, 3}}

带有 map 的示例:

m := map[string]interface{}{
    "Results": results,
    "Other":   []int{1, 2, 3},
}

if err := GetTemplate("list").Execute(w, m); err != nil {
    // Handle error
}

请注意,使用地图时,不需要使用大写的 string 作为键,例如你也可以使用 "results""other" (但在我看来,最好使用大写首字母的键,如果你将来有时移动到 struct ,你会更少要进行的更正)。

在这两种情况下,您都可以使用 {{.Results}} 引用 []User 结果,并使用 {{.Other}}.

引用附加的 int 切片

因此,例如要覆盖用户:

{{range .Results}}
    User name:{{.Name}}
{{end}}

带有 slice 的示例:

s := []interface{}{
    results,
    []int{1, 2, 3},
}

if err := GetTemplate("list").Execute(w, s); err != nil {
    // Handle error
}

这不太可读,但却是一个可行的解决方案。在模板中,您必须索引模板数据以获取 "individual" 值,例如:

{{range index . 0}}
    User name:{{.Name}}
{{end}}

Other: {{index . 1}}

Go Playground 上试用。

其他方式...

还有其他 "theoretical" 方法,但我不会仅仅因为它有效就使用它们。

例如,您还可以传入一个通道,接收者将从该通道提供值。

另一种解决方案可能是 ,调用时会 return 值。

您应该定义一个填充有数据库结果查询的结构,然后将该结构分配给 Execute 方法。

tmpl.Execute 需要一个 Writer 接口和一个 struct

type Inventory struct {
    Material string
    Count    uint
}

items := Inventory{"trouser", 1}    
if err := GetTemplate("list").Execute(w, items); err != nil {
    // ... do your work
}

您可以使用 range 关键字将您的结构放入另一个结构中。例如

type Data struct {
    Users  []User
    Developers []Developer
}


var data = Data{
    Users:  ...,
    Developers: ...,
}

err := t.Execute(w, &data)
if err != nil {
    panic(err)
}

{{range .Users}}{{.UserName}}
{{end}}
{{range .Developers}}{{.DeveloperName}}
{{end}}