如何传递多个对象去模板?

时间:2014-05-22 08:50:40

标签: templates go

我能找到的大多数例子都描述了非常简单/基本的东西,比如显示像这样的人物对象的属性:

The name is {{.Name}}. The age is {{.Age}}.

如果您有一个更复杂的网页会发生什么,例如,多个不同的对象和对象列表,例如,您如何做这样的事情:

{{p.Name}} is aged {{p.Age}}. 
Outstanding invoices {{invoices.Count}} 

<table>
<tr><td>{{invoices[0].number}}</td></tr>
.... etc...

3 个答案:

答案 0 :(得分:7)

您可以声明并传入一个匿名结构,如下所示:

templ.Execute(file, struct {
    Age int
    Name string
}{42, "Dolphin"})

并访问变量,如:

{{.Age}}, {{.Name}}

虽然这仍然需要你制作一个结构,但它是最简洁的方法之一。你必须决定它是否对你来说太难看了;)

答案 1 :(得分:5)

您可以将更复杂的数据放入struct中,并像传递NameAge一样传递它。例如,

type vars struct {
    P User
    Invoices []Invoice
}

type User struct {
    Name string
    Age int
}

type Invoice {
    Number int
    Description string
}

如果将vars的实例传递给模板执行,则可以使用点和数组索引来引用子结构,就像常规go代码一样。

{{.P.Name}}, {{.P.Age}}, {{.Invoices[0].Number}}

答案 2 :(得分:1)

这取决于您的数据。 我想对此进行分类。

  1. 模板的主要数据。在你的例子中,这将是Invoice / Invoicelist。如果您必须传递多个,则必须重新考虑模板设计。
  2. 辅助数据,例如登录的用户信息或您发现自己传递到多个模板的任何常见信息。
  3. 由于这些信息很常见。我通常把它们变成功能。由于这些功能不能有输入参数。您可能希望将它们创建为闭包(在另一个函数中)。将这些函数分配给funMap,并在解析后将其添加到模板中。

    func MakeFuncMap(u *user) map[string]interface{} {
        return map[string]interface{}{
            "User": func() *user {return u}, //Can be accessed by "User." within your template
        }
    }
    
    t, err := template.New("tmpl").Funcs(MakeFuncMap(nil)).Parse("template") //You will need to append a dummy funcMap as you will not have access to User at the time of template parsing
    
    //You will have to clone the template to make it thread safe to append funcMap.
    tClone, _ := t.Clone()
    tClone.Funcs(MakeFuncMap(u)).Execute(w, invoicelist)
    

    现在您可以仅使用invoicelist作为数据来执行模板。 在您的模板中,您应该能够使用“用户”访问用户信息。和发票清单“。”

    您应该能够为所有常见数据定义一次funcMap。这样你就可以重复使用它。

    要循环通过一个发票人,你可以查看范围

    {{range .}} //if you are passing invoicelist then the . means invoicelist
       //in here . means each of the invoice
       <label>{{User.Name}}, {{User.Age}}</label>
       <label>{{.Id}}</label>
    {{end}}
    

    编辑:Ripounet指出的问题包含修复