【问题标题】:How to pass multiple data to Go template?如何将多个数据传递给 Go 模板?
【发布时间】:2016-05-15 10:12:24
【问题描述】:

我想将两个数据对象传递给 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,???????)

如果只有 db 结果,我们可以将其用作

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

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

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

【问题讨论】:

    标签: go go-templates


    【解决方案1】:

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

    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
    }
    

    请注意,使用地图时,不需要使用大写的strings 作为键,例如您也可以使用"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
    }
    

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

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

    在Go Playground 上试用。

    其他方式...

    还有其他“理论上的”方法,但我不会仅仅因为它有效而使用它们。

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

    另一个解决方案可能是register custom functions,它在调用时会返回值。

    【讨论】:

      【解决方案2】:

      您应该定义一个填充了数据库结果查询的结构,然后将该结构分配给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
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 1970-01-01
        • 2012-02-15
        • 2018-11-01
        相关资源
        最近更新 更多