Go template中range循环内调用子模板如何正确传递外层上下文
问题原因
Go Template 的 {{ range }} 循环会重写当前上下文 . 的值,循环内的 . 默认指向当前迭代的元素,而非循环外的根上下文。你在循环内直接传 . 给子模板,实际传入的是当前迭代的 $instance 变量,和循环外传入的根上下文不是同一个对象,因此子模板访问原根上下文的字段时就会抛出类型不匹配错误。
解决方案
方案1:仅需传递根上下文到子模板
在进入 range 循环前,先将根上下文赋值给一个带 $ 前缀的顶级变量,这类变量不会被循环的上下文覆盖,循环内直接传递该变量即可:
{{/* 提前保存根上下文 */}} {{ $root := . }} {{ range $instance := .Instances }} - type: instance metadata: userdata: {{ template "userdata" $root }} {{ end }}
此时子模板 userdata 内的 . 和循环外调用时完全一致,原有子模板代码不需要修改。
方案2:需要同时传递根上下文和当前迭代实例
如果子模板既要用到原根上下文的字段,又要用到当前循环的 $instance 信息,可以用内置的 dict 函数构造自定义上下文传递:
{{ $root := . }} {{ range $instance := .Instances }} - type: instance metadata: userdata: {{ template "userdata" (dict "Root" $root "Instance" $instance) }} {{ end }}
在子模板 userdata 中可以通过 .Root.XXX 访问原根上下文的字段,通过 .Instance.XXX 访问当前迭代实例的字段。
内容的提问来源于stack exchange,提问作者Igor Chubin
相关产品推荐
相关产品推荐

