给定一组结构,我如何使用“范围”模板迭代器打印出一个表,该表为每个结构分配一行,为每个字段值分配一列,而无需显式命名字段?
container := []Node
type Node struct {
Contact_id int
Employer_id int
First_name string
Middle_name string
Last_name string
}
模板代码:
{{range .container}}
<tr>
<td>{{.Prefix}}</td>
<td>{{.First_name}}</td>
<td>{{.Middle_name}}</td>
<td>{{.Last_name}}</td>
<td>{{.Contact_id}}</td>
<td>{{.Employer_id}}</td>
</tr>
{{end}}
当我尝试使用迭代值时
{{range .container}}
{{range .}}
<td>{{.}}</td>
{{end}}
{{end}}
有人告诉我,我无法遍历价值观。有什么干净的方法可以做到这一点吗?
使用html/template
,您无法遍历结构中的字段。在该包的文档中,您可以阅读:
{{范围管道}} T1 {{end}}
管道的值必须是数组,切片,映射或通道。
也就是说,管道不能是结构。您需要:
[][]interface{}
,作为您传递到模板的容器变量由于结构是在编译时定义的,并且在运行时不会更改其结构,因此不需要迭代,也不会使模板中的内容更加清楚。我不建议这样做。
编辑
但是有时候反思是一件好事。布伦登还指出,您实际上可以让range迭代从函数返回的值。如果使用反射,这将是最简单的方法。
使用模板功能的完整工作示例:
package main
import (
"html/template"
"os"
"reflect"
)
type Node struct {
Contact_id int
Employer_id int
First_name string
Middle_name string
Last_name string
}
var templateFuncs = template.FuncMap{"rangeStruct": RangeStructer}
// In the template, we use rangeStruct to turn our struct values
// into a slice we can iterate over
var htmlTemplate = `{{range .}}<tr>
{{range rangeStruct .}} <td>{{.}}</td>
{{end}}</tr>
{{end}}`
func main() {
container := []Node{
{1, 12, "Accipiter", "ANisus", "Nisus"},
{2, 42, "Hello", "my", "World"},
}
// We create the template and register out template function
t := template.New("t").Funcs(templateFuncs)
t, err := t.Parse(htmlTemplate)
if err != nil {
panic(err)
}
err = t.Execute(os.Stdout, container)
if err != nil {
panic(err)
}
}
// RangeStructer takes the first argument, which must be a struct, and
// returns the value of each field in a slice. It will return nil
// if there are no arguments or first argument is not a struct
func RangeStructer(args ...interface{}) []interface{} {
if len(args) == 0 {
return nil
}
v := reflect.ValueOf(args[0])
if v.Kind() != reflect.Struct {
return nil
}
out := make([]interface{}, v.NumField())
for i := 0; i < v.NumField(); i++ {
out[i] = v.Field(i).Interface()
}
return out
}
输出:
<tr>
<td>1</td>
<td>12</td>
<td>Accipiter</td>
<td>ANisus</td>
<td>Nisus</td>
</tr>
<tr>
<td>2</td>
<td>42</td>
<td>Hello</td>
<td>my</td>
<td>World</td>
</tr>
操场
生成器迭代 手动迭代生成器,递归执行 AsyncTask::next,调用Generator::send方法将将yield值作为yield表达式结果。 yield表达式可能是一个异步调用,我们这里为之后把异步调用的结果作为yield表达式结果铺垫。 yield外侧括号在PHP5必须,PHP7不需要。 如, $ip = (yield async_dns_lookup(...) ); ^
|--themes |--simplebootx //模板目录 |--Comment |--comment.html //评论模板,{:Comments()}中会调用 |--index.html //用户中心评论模板(链接:comment/
ThinkCMF模板目录结构如下: |--themes |--simplebootx |--Portal |--index.html 模板开发时我们仅需要在themes目录下创建一个模板文件夹,假设为simplebootx,simplebootx文件夹下我们需要创建一个应用名称的文件夹,比如Portal。一般情况下我们还会创建一个Public文件夹用来存放公共的css,j
我有一个类,声明如下:comparator: 搜索功能不转换条件: 你能帮忙吗? 翻译错误: main.cpp:101:44:从这里实例化 main.cpp:55:13: 错误: 与调用 '(const std::equal_to) 不匹配(const std::p air
我有一个由以下字符|分隔的csv文件。该文件有三列;一个是url(COL1),另一个是小文本(COL3),最后一个是图像位置(COL2)。我需要一个脚本,用csv文件中的数据给我这样的html代码: 我该怎么做?
这篇内容挺多的,而且比内容不好理解。或许新手看完后,还会一脸懵逼,不过这是正常的,如果你看完后,是迷糊的,那么建议你继续学习后面的内容,等学完,再回来看几次。 注:这也是我第二次修改内容没有改过的章节。 目录