如何访问模板中的结构字段

How to access struct fields in a template

我想在范围循环内比较两个字符串类型的变量,如下所示:

<select name="category" id="category">            
    {{range $c := .cats}}
      <option value="{{$c.Title}}"  {{ if eq $c.Title .category}}active{{end}}>{{$c.Title}}</option>                                       
    {{end}}    
</select>

$c.Titlecategory都是控制器发送的字符串。

但是,在呈现模板中的下拉菜单中,我得到:

can't evaluate field category in type model.category

$c属于结构类型类别:

type Category struct {
    ID        int       `db:"id"`
    Title     string    `db:"title"`
    Slug      string    `db:"slug"`
    CreatedAt time.Time `db:"created_at"`
}

当我在上面的代码中直接输入 category 而不是 .category 的字符串值时,没有问题。
我正在使用 gowebapp MVC 框架,如果它确实重要的话。

我该如何解决这个问题?

您要比较的 .category 值不是 model 的一部分,但模板引擎将尝试将 .category 解析为 category 作为字段或者你的 model 值的方法。

这是因为 {{range}} 操作将点 . 设置为每次迭代中的连续元素。

要引用 top-level category,您可以像这样使用 $ 符号:

<select name="category" id="category">            
    {{range $c := .cats}}
      <option value="{{$c.Title}}"  {{ if eq $c.Title $.category}}active{{end}}>{{$c.Title}}</option>                                       
    {{end}}    
</select>

查看这个可运行的示例:

func main() {
    t := template.Must(template.New("").Parse(src))
    params := map[string]interface{}{
        "category": "Cars",
        "cats": []struct{ Title string }{
            {"Animals"}, {"Cars"}, {"Houses"},
        },
    }
    if err := t.Execute(os.Stdout, params); err != nil {
        panic(err)
    }
}

const src = `<select name="category" id="category">            
    {{range $c := .cats}}
      <option value="{{$c.Title}}"  {{ if eq $c.Title $.category}}active{{end}}>{{$c.Title}}</option>                                       
    {{end}}    
</select>`

输出(在 Go Playground 上尝试):

<select name="category" id="category">            

      <option value="Animals"  >Animals</option>

      <option value="Cars"  active>Cars</option>

      <option value="Houses"  >Houses</option>

</select>