Go模板:无法在类型Y中评估字段X(X不是Y的一部分,但卡在{{range}}循环中)

huangapple go评论90阅读模式
英文:

Go template: can't evaluate field X in type Y (X not part of Y but stuck in a {{range}} loop)

问题

类似的问题在这里得到了解答,但我不认为它解决了我的问题。

假设你有以下结构体:

type User struct {
    Username string
    Password []byte
    Email string
    ...
}

此外,URL 的结构如下:example.com/en/users,其中 "en" 是一个 URL 参数,将被传递到模板中,如下所示:

renderer.HTML(w, http.StatusOK, "users/index", map[string]interface{}{
  "lang": chi.URLParam(r, "lang"),
  "users": users})

在 HTML 模板中,我有以下内容:

{{ range .users }}
  <form action="/{{ .lang }}/users" method="POST">
    <input type="text" name="Username" value="{{ .Username }}">
    <input type="text" name="Email" value="{{ .Email }}">
  </form>
{{ end }}

现在的问题是,因为 {{ .lang }} 不是 User 结构体的一部分,所以我会得到错误。那么,我如何在 {{ range .users }} 内部访问 {{ .lang }}

英文:

Similar question answered here, but I don't think it solves my problem.

Let's say you have the following struct:

type User struct {
    Username string
    Password []byte
    Email string
    ...
}

Moreover, the URL hasa structure like this: example.com/en/users, where &quot;en&quot; is a URL param that will be passed into the template like this:

renderer.HTML(w, http.StatusOK, &quot;users/index&quot;, map[string]interface{}{
  &quot;lang&quot;:  chi.URLParam(r, &quot;lang&quot;),
  &quot;users&quot;: users})

And in the HTML template I have the following:

{{ range .users }}
  &lt;form action=&quot;/{{ .lang }}/users&quot; method=&quot;POST&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Username&quot; value=&quot;{{ .Username }}&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Email&quot; value=&quot;{{ .Email }}&quot;&gt;
  &lt;/form&gt;
{{ end }}

Now, the problem is that because {{ .lang }} is not a part of the User struct then I get the error.. so how can I access {{ .lang }} inside {{ range .users }}?

答案1

得分: 50

在调用range之后,点号(.)的内容被赋值给$,因此您可以使用$来访问lang在play中查看):

{{ range .users }}
  <form action="/{{ $.lang }}/users" method="POST">
    <input type="text" name="Username" value="{{ .Username }}">
    <input type="text" name="Email" value="{{ .Email }}">
  </form>
{{ end }}

该行为在这里有文档记录:

当执行开始时,$被设置为传递给Execute的数据参数,也就是点号的初始值。

如果您正在使用嵌套的range,您可以始终使用with语句或变量赋值语句将点号赋值给其他变量。请参阅另一个答案

英文:

The contents of dot (.) are assigned to $ after invocation of range, so you can use $ to access lang (on play):

{{ range .users }}
  &lt;form action=&quot;/{{ $.lang }}/users&quot; method=&quot;POST&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Username&quot; value=&quot;{{ .Username }}&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Email&quot; value=&quot;{{ .Email }}&quot;&gt;
  &lt;/form&gt;
{{ end }}

The behavior is documented here:

> When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.

If you are using nested ranges, you can always fall back to assign dot to something else using the with statement or variable assignment statements. See the other answer for that.

答案2

得分: 11

你可以使用一个变量来表示.lang

{{ $lang := .lang }}
{{ range .users }}
  <form action="/{{ $lang }}/users" method="POST">
    <input type="text" name="Username" value="{{ .Username }}">
    <input type="text" name="Email" value="{{ .Email }}">
  </form>
{{ end }}

在这里查看文档:https://golang.org/pkg/text/template/#hdr-Variables

英文:

You can use a variable for .lang

{{ $lang := .lang }}
{{ range .users }}
  &lt;form action=&quot;/{{ $lang }}/users&quot; method=&quot;POST&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Username&quot; value=&quot;{{ .Username }}&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;Email&quot; value=&quot;{{ .Email }}&quot;&gt;
  &lt;/form&gt;
{{ end }}

See here at the documentation: https://golang.org/pkg/text/template/#hdr-Variables

huangapple
  • 本文由 发表于 2017年4月7日 02:38:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/43263280.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定