You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go的html/template中用非关联数据实现嵌套range循环

问题

希望在Go的html/template中实现嵌套range循环,示例代码如下:

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 }}的子字段。单独使用单个range或连续使用两个range均能正常运行。请问能否使用与外层range无关联的数据实现嵌套range循环?

解决方案

当然可以实现。问题核心是嵌套range中的.Setting默认指向当前Runtest对象的上下文,但Runtest结构体并没有Setting字段,所以触发报错。以下两种方法可解决该问题:

方式一:用$引用根级上下文数据

Go模板中,$始终代表最顶层的原始数据上下文,不受嵌套层级影响。只需修改内部range的引用方式:

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 }}
`))

方式二:提前将根数据赋值给变量

在外层range开始前,把根级的Setting数据赋值给一个独立变量,嵌套中直接使用该变量即可:

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

这两种方式都能让内部range遍历与外层Runtest无关的Setting数据,彻底解决报错问题。

内容的提问来源于stack exchange,提问作者nexty5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:33:28