只有当 []struct 不为空时才继续进行。

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

Only proceed if []struct is not empty

问题

我有一个 []struct,它可以没有内容,但也有可能有内容:

Anleitung []struct {
    Name string `json:"blog"`
    Link string `json:"link"`
} `json:"anleitung"`

在我的模板中,我尝试检查 Anleitung 是否包含内容,只有在有内容的情况下才继续执行:

{{ if ne $jb.Anleitung "" }}
    <div class="btn-group">
        <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span class="badge">4</span> Anleitungen <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            {{ range $anl := $jb.Anleitung }}
                <li><a href="{{ $anl.Link }}?ref=jbguide">{{ $anl.Name }}</a></li>
            {{ end }}
        </ul>
    </div>
{{ end }}

编译整个代码会给出以下错误:

Error rendering index template: template: index.tmpl:131: unexpected {{end}}

第 131 行是模板文件的最后一行。

有没有办法检查 []struct 是否包含任何数据?

英文:

I have an []struct that can have no content but also it is possible that it has content:

Anleitung  []struct {
    Name string `json:&quot;blog&quot;`
    Link string `json:&quot;link&quot;`
} `json:&quot;anleitung&quot;`

In my template I try to check if Anleitung contains something, and only then proceed:

{{ ne $jb.Anleitung &quot;&quot; }}
     &lt;div class=&quot;btn-group&quot;&gt;
        &lt;button type=&quot;button&quot; class=&quot;btn btn-info dropdown-toggle&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;
              &lt;span class=&quot;badge&quot;&gt;4&lt;/span&gt; Anleitungen &lt;span class=&quot;caret&quot;&gt;&lt;/span&gt;
        &lt;/button&gt;
        &lt;ul class=&quot;dropdown-menu&quot;&gt;
            {{ range $anl := $jb.Anleitung }}
                 &lt;li&gt;&lt;a href=&quot;{{ $anl.Link }}?ref=jbguide&quot;&gt;{{ $anl.Name }}&lt;/a&gt;&lt;/li&gt;
             {{ end }}
         &lt;/ul&gt;
      &lt;/div&gt;
{{ end }}

compiling the whole thing gives me the following error:
> Error rendering index template: template: index.tmpl:131: unexpected {{end}}

Row no 131 is the last row in the template file.

Is there a way to check if the []struct contains any data?

答案1

得分: 3

你可以简单地使用{{with}}操作。引用自text/template包的文档:

{{with pipeline}} T1 {{end}}
如果pipeline的值为空,则不生成任何输出;
否则,将dot设置为pipeline的值,并执行T1。

由于{{with}}也设置了pipeline,将你的{{range}}修改为以下内容:

{{ range $anl := . }}

使用它:

{{ with $jb.Anleitung }}
    <div class="btn-group">
        <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span class="badge">4</span> Anleitungen <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            {{ range $anl := . }}
                <li><a href="{{ $anl.Link }}?ref=jbguide">{{ $anl.Name }}</a></li>
            {{ end }}
        </ul>
    </div>
{{ end }}

进一步简化{{range}},因为我们不需要$anl变量,{{range}}也会设置pipeline:

{{ range . }}
    <li><a href="{{.Link}}?ref=jbguide">{{.Name}}</a></li>
{{ end }}

测试代码:

t := template.Must(template.New("").Parse(templ))
m := map[string]interface{}{}
fmt.Println("First, no params:")
if err := t.Execute(os.Stdout, m); err != nil {
    fmt.Println(err)
}

fmt.Println("Next, 2 values:")
m = map[string]interface{}{
    "Anleitung": []struct {
        Name string `json:"blog"`
        Link string `json:"link"`
    }{
        {"Bob", "http://google.com"},
        {"Alice", "http://amazon.com"},
    },
}
if err := t.Execute(os.Stdout, m); err != nil {
    fmt.Println(err)
}

输出结果(在Go Playground上尝试):

First, no params:

Next, 2 values:


    <div class="btn-group">
        <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span class="badge">4</span> Anleitungen <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
            
            <li><a href="http://google.com?ref=jbguide">Bob</a></li>
            
            <li><a href="http://amazon.com?ref=jbguide">Alice</a></li>
            
        </ul>
    </div>
英文:

You may simply use the {{with}} action. Quoting from the package doc of text/template:

{{with pipeline}} T1 {{end}}
	If the value of the pipeline is empty, no output is generated;
	otherwise, dot is set to the value of the pipeline and T1 is
	executed.

Since {{with}} also sets the pipeline, modify your {{range}} to this:

{{ range $anl := . }}

Using it:

{{ with $jb.Anleitung }}
     &lt;div class=&quot;btn-group&quot;&gt;
        &lt;button type=&quot;button&quot; class=&quot;btn btn-info dropdown-toggle&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;
              &lt;span class=&quot;badge&quot;&gt;4&lt;/span&gt; Anleitungen &lt;span class=&quot;caret&quot;&gt;&lt;/span&gt;
        &lt;/button&gt;
        &lt;ul class=&quot;dropdown-menu&quot;&gt;
            {{ range $anl := . }}
                 &lt;li&gt;&lt;a href=&quot;{{ $anl.Link }}?ref=jbguide&quot;&gt;{{ $anl.Name }}&lt;/a&gt;&lt;/li&gt;
             {{ end }}
         &lt;/ul&gt;
      &lt;/div&gt;
{{ end }}

Going further, you can simplify the {{range}} as we don't need the $anl variable, {{range}} also sets the pipeline:

{{ range . }}
    &lt;li&gt;&lt;a href=&quot;{{.Link}}?ref=jbguide&quot;&gt;{{.Name}}&lt;/a&gt;&lt;/li&gt;
{{ end }}

Testing it:

t := template.Must(template.New(&quot;&quot;).Parse(templ))
m := map[string]interface{}{}
fmt.Println(&quot;First, no params:&quot;)
if err := t.Execute(os.Stdout, m); err != nil {
	fmt.Println(err)
}

fmt.Println(&quot;Next, 2 values:&quot;)
m = map[string]interface{}{
	&quot;Anleitung&quot;: []struct {
		Name string `json:&quot;blog&quot;`
		Link string `json:&quot;link&quot;`
	}{
		{&quot;Bob&quot;, &quot;http://google.com&quot;},
		{&quot;Alice&quot;, &quot;http://amazon.com&quot;},
	},
}
if err := t.Execute(os.Stdout, m); err != nil {
	fmt.Println(err)
}

Output (try it on the Go Playground):

First, no params:

Next, 2 values:


     &lt;div class=&quot;btn-group&quot;&gt;
        &lt;button type=&quot;button&quot; class=&quot;btn btn-info dropdown-toggle&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;
              &lt;span class=&quot;badge&quot;&gt;4&lt;/span&gt; Anleitungen &lt;span class=&quot;caret&quot;&gt;&lt;/span&gt;
        &lt;/button&gt;
        &lt;ul class=&quot;dropdown-menu&quot;&gt;
            
                 &lt;li&gt;&lt;a href=&quot;http://google.com?ref=jbguide&quot;&gt;Bob&lt;/a&gt;&lt;/li&gt;
             
                 &lt;li&gt;&lt;a href=&quot;http://amazon.com?ref=jbguide&quot;&gt;Alice&lt;/a&gt;&lt;/li&gt;
             
         &lt;/ul&gt;
      &lt;/div&gt;

答案2

得分: 1

两件事情:

  1. 你的 ne 语法是错误的。它需要以 if 开头,然后你的 {{ end }} 就不会再是语法错误了。
  2. 你的结构体永远不会等于 &quot;&quot;,因为它不是一个字符串。如果你想知道切片是否为空,你必须检查它的长度。在模板中实现这个的方法是使用 pipeline,如文档所述,这将使 #1 成为过时的。
英文:

Two things:

  1. Your ne syntax is wrong. It needs to begin with if, then your {{ end }} will no longer be a syntax error.
  2. Your struct is never going to equal &quot;&quot;, because it's not a string. If you want to know if the slice is empty, you must check its length. The way to do this in a template is, as documented, with pipeline. This will, in effect, render #1 obsolete.

huangapple
  • 本文由 发表于 2017年2月22日 17:12:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/42387123.html
匿名

发表评论

匿名网友

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

确定