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

前端之家收集整理的这篇文章主要介绍了转到template / html迭代以从struct生成表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
给定一个结构集合,如何使用“范围”模板迭代器打印出一个表,该表为每个结构分配一行,每个字段的列没有明确指定字段?
  1. container := []Node
  2.  
  3. type Node struct {
  4. Contact_id int
  5. Employer_id int
  6. First_name string
  7. Middle_name string
  8. Last_name string
  9. }

模板代码

  1. {{range .container}}
  2.  
  3. <tr>
  4. <td>{{.Prefix}}</td>
  5. <td>{{.First_name}}</td>
  6. <td>{{.Middle_name}}</td>
  7. <td>{{.Last_name}}</td>
  8.  
  9. <td>{{.Contact_id}}</td>
  10. <td>{{.Employer_id}}</td>
  11.  
  12. </tr>
  13. {{end}}

当我尝试使用迭代值时

  1. {{range .container}}
  2. {{range .}}
  3. <td>{{.}}</td>
  4. {{end}}
  5. {{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还指出,您实际上可以让范围迭代函数返回的值.如果使用反射,这将是最简单的方法.

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

  1. package main
  2.  
  3. import (
  4. "html/template"
  5. "os"
  6. "reflect"
  7. )
  8.  
  9. type Node struct {
  10. Contact_id int
  11. Employer_id int
  12. First_name string
  13. Middle_name string
  14. Last_name string
  15. }
  16.  
  17. var templateFuncs = template.FuncMap{"rangeStruct": RangeStructer}
  18.  
  19. // In the template,we use rangeStruct to turn our struct values
  20. // into a slice we can iterate over
  21. var htmlTemplate = `{{range .}}<tr>
  22. {{range rangeStruct .}} <td>{{.}}</td>
  23. {{end}}</tr>
  24. {{end}}`
  25.  
  26. func main() {
  27. container := []Node{
  28. {1,12,"Accipiter","ANisus","Nisus"},{2,42,"Hello","my","World"},}
  29.  
  30. // We create the template and register out template function
  31. t := template.New("t").Funcs(templateFuncs)
  32. t,err := t.Parse(htmlTemplate)
  33. if err != nil {
  34. panic(err)
  35. }
  36.  
  37. err = t.Execute(os.Stdout,container)
  38. if err != nil {
  39. panic(err)
  40. }
  41.  
  42. }
  43.  
  44. // RangeStructer takes the first argument,which must be a struct,and
  45. // returns the value of each field in a slice. It will return nil
  46. // if there are no arguments or first argument is not a struct
  47. func RangeStructer(args ...interface{}) []interface{} {
  48. if len(args) == 0 {
  49. return nil
  50. }
  51.  
  52. v := reflect.ValueOf(args[0])
  53. if v.Kind() != reflect.Struct {
  54. return nil
  55. }
  56.  
  57. out := make([]interface{},v.NumField())
  58. for i := 0; i < v.NumField(); i++ {
  59. out[i] = v.Field(i).Interface()
  60. }
  61.  
  62. return out
  63. }

输出

  1. <tr>
  2. <td>1</td>
  3. <td>12</td>
  4. <td>Accipiter</td>
  5. <td>ANisus</td>
  6. <td>Nisus</td>
  7. </tr>
  8. <tr>
  9. <td>2</td>
  10. <td>42</td>
  11. <td>Hello</td>
  12. <td>my</td>
  13. <td>World</td>
  14. </tr>

Playground

猜你在找的HTML相关文章