加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

转到template / html迭代以从struct生成表

发布时间:2020-12-24 23:15:55 所属栏目:资源 来源:网络整理
导读:给定一个结构集合,如何使用“范围”模板迭代器打印出一个表,该表为每个结构分配一行,每个字段的列没有明确指定字段? container := []Nodetype Node struct { Contact_id int Employer_id int First_name string Middle_name string Last_name string} 模板

给定一个结构集合,如何使用“范围”模板迭代器打印出一个表,该表为每个结构分配一行,每个字段的列没有明确指定字段?

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,您无法遍历结构中的字段.在包装的 documentation中,您可以阅读:

{{range pipeline}} T1 {{end}}
The value of the pipeline must be an array,slice,map,or channel.

也就是说,Pipeline不能是一个struct.要么你需要:

>使用中间类型,例如. [] [] interface {},作为传递给模板的容器变量
>如您所示,分别输入每个单元格
>创建一个模板函数,将结构值转换为可以迭代的某种类型

由于struct是在编译时定义的,并且在运行时不会更改其结构,因此迭代不是必需的,并且不会使模板中的内容更清晰.我会反对它.

编辑

但有时反思是件好事. Brenden还指出,您实际上可以让范围迭代函数返回的值.如果使用反射,这将是最简单的方法.

使用模板函数的完整工作示例:

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>

Playground

(编辑:威海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读