html 创建映射,在Go HTML模板中创建结构映射键的语法

我正在编写一个简单的Go程序,以显示每个环境的已部署服务版本的HTML表。 我的程序包含以下结构:

type versionKey struct {

Environment string

Service     string

}

type templateData struct {

Environments []string

Services     []string

Versions     map[versionKey]string

}

如您所见,Versions映射使用versionKey作为字符串值的键,例如 "1.0.0"。

我将templateData结构传递给HTML模板,并遍历其Environments和Services切片以构建HTML表。 问题是我需要为任何给定的环境和服务的交集构造一个versionKey,因此我可以使用它从Versions映射中查找版本并在表单元格中输出该值。

在模板中,我可以从范围中使用$environment和$service变量,但是我无法计算Go模板语法来创建versionKey结构。

这是省略了标记的模板代码:

{{$environments := .Environments}}

{{$services := .Services}}

{{$versions := .Versions}}

{{range $service := $services}}

...

{{range $environment := $environments}}

...

{{index $versions ...? }} // How to create versionKey struct map key here?

...

{{end}}

...

{{end}}

仅使用模板代码就不能。您需要执行的Go代码提供某种支持才能做到这一点。按照设计原则,模板不应包含复杂的逻辑。您可能会争论这是否复杂,但是模板语法对此不提供支持。

最简单的解决方案是在templateData结构中添加一个Version()方法,该方法将简单地返回给定环境和服务的版本:

func (t *templateData) Version(environment, service string) string {

return t.Versions[versionKey{

Environment: environment,

Service:     service,

}]

}

在模板中使用它:

{{range $service := $services -}}

{{range $environment := $environments}}

{{$environment}} - {{$service}} version: {{$.Version $environment $service}}

{{end}}

{{end}}

测试它:

t := template.Must(template.New("").Parse(templ))

td := &templateData{

Environments: []string{"EnvA","EnvB"},

Services:     []string{"ServA","ServB"},

Versions: map[versionKey]string{

{"EnvA","ServA"}:"1.0.0",

{"EnvA","ServB"}:"1.0.1",

{"EnvB","ServA"}:"1.0.2",

},

}

if err := t.Execute(os.Stdout, td); err != nil {

panic(err)

}

输出(在Go Playground上尝试):

EnvA - ServA version: 1.0.0

EnvB - ServA version: 1.0.2

EnvA - ServB version: 1.0.1

EnvB - ServB version:

备择方案

代替templateData.Version()方法,您可以轻松地注册一个函数,该函数可以从给定的环境和服务创建并返回类型为versionKey的值。有关详细信息,请参见Template.Funcs()。但是,这将更加复杂,但由于可以在其他地方重用而更加灵活。在此处查看以下示例:Golang模板(以及将funcs传递到模板)。对此的微小变化是将函数值作为任何其他模板数据传递,而不是将其注册为可调用的命名函数。

另一种替代方法是将您的Versions字段"转换"为地图,例如:

Versions map[string]map[string]string

首先可以由环境索引,然后由服务索引,您可以在模板中通过2个{{index}}动作实现索引。您将不得不检查第一个索引是否产生任何结果。

很棒的答案,非常感谢。 出于兴趣,为什么对templateData使用指针?

@JohnTopley两者(指针和非指针接收器)都可以在此简单示例中工作。 我完全出于习惯使用了指针接收器,如果示例演变为一个更复杂的方法,其中方法还需要更改/修改接收器,那么我不必回头将接收器更改为指针接收器。

我了解-谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值