如何使用 html/template 在 golang 中运行一个范围内的范围

问题描述 投票:0回答:1

我想使用 html/template 运行一个范围内的范围。示例代码(https://go.dev/play/p/fxx61RwIDhd)如下所示:

package main

import (
    "html/template"
    "os"
)

type Runtest struct {
    ID          int
    SessionType string
}

type Setting struct {
    ID   int
    Type string
}

type templateData struct {
    Runtest []*Runtest
    Setting []*Setting
}

func main() {
    tmpl := template.Must(template.New("nested-range").Parse(`
        {{ range .Runtest }}
            <h1>Runtest ID: {{ .ID }}, Session Type: {{ .SessionType }}</h1>
            <ul>
                {{ range .Setting }}
                    <li>Setting ID: {{ .ID }}, Type: {{ .Type }}</li>
                {{ end }}
            </ul>
        {{ end }}
    `))

    runtestsList := []*Runtest{
        {ID: 1, SessionType: "Type A"},
        {ID: 2, SessionType: "Type B"},
    }

    settingsList := []*Setting{
        {ID: 101, Type: "Setting 1"},
        {ID: 102, Type: "Setting 2"},
        {ID: 201, Type: "Setting X"},
        {ID: 202, Type: "Setting Y"},
    }

    data := templateData{
        Runtest: runtestsList,
        Setting: settingsList,
    }

    err := tmpl.Execute(os.Stdout, data)
    if err != nil {
        panic(err)
    }
}

执行代码时出现以下错误:

panic: template: nested-range:5:13: executing "nested-range" at <.Setting>: can't evaluate field Setting in type *main.Runtest

模板引擎似乎将 {{ range .Setting }} 视为 {{ range .Runtest }} 的一部分。

如果您仅尝试使用一个范围,则代码将起作用:https://go.dev/play/p/CUOxnBfvAo1

也是一个又一个的范围:https://go.dev/play/p/mge2JsQYOYD

是否可以使用不属于第一个范围数据的数据来运行范围内的范围?

go go-templates go-html-template
1个回答
0
投票

这是一个范围界定问题。

range
启动一个新范围,迭代变量为
.
。也就是说,当你有

{{range .Runtest}}
  // Here . points to the current element of the Runtest

您仍然可以使用

$
前缀引用全局范围内的变量:

 {{ range .Runtest }}
            <h1>Runtest ID: {{ .ID }}, Session Type: {{ .SessionType }}</h1>
            <ul>
                {{ range $.Setting }}

或者,您可以自己定义循环变量。如果您有多个级别的

range
并且您需要访问其中一个封闭级别中定义的变量,这尤其有用:

{{ range $key1, $value1 := .someList }}
   {{ range $key2, $value2 := $value1.otherList }}
      // Here, you can access both $value1 and $value2, 
      // as well as the global scope $.GlobalScopeVar
© www.soinside.com 2019 - 2024. All rights reserved.