如何发送一组地图并使用gin-templating迭代它

时间:2021-07-25 14:26:34

Following is the snippet of a working code. I am using gin templating engine.

以下是工作代码的片段。我正在使用杜松子酒模板引擎。

c.HTML(200, "index", gin.H{
            "title":    "Welcome",
            "students": map[int]map[string]string{1: {"PID": "1", "Name": "myName"}},})

And in index template I have:

在索引模板中,我有:

 <TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>
        {{range $student := .students}}
        <td>{{$student.Name}}</td>                    
        {{end}}
 </TABLE>

As you can see I have hard-coded the value of students on the headers (the map). I want to have this data from a rest API that I have built. the response of my rest API is an array:

正如您所看到的,我在标题(地图)上对学生的价值进行了硬编码。我希望从我构建的其他API获取此数据。我的rest API的响应是一个数组:

 [
  {
    "id": 1,
    "name": "Mary"
  },
  {
    "id": 2,
    "name": "John"
  }
]

I can unmarshal this JSON response into map[string]string instead of map[int]map[string]string. How can pass this unmarhsaled body in parameter value for students and then iterate over this array the index template?

我可以将这个JSON响应解组为map [string]字符串而不是map [int] map [string]字符串。如何在学生的参数值中传递这个未经管理的正文,然后在这个数组上迭代索引模板?

1 个解决方案

#1


1  

With a struct

What you have is a JSON array, unmarshal it into a Go slice. Recommended to create a Student struct to model your students to have a clean and conscious Go code.

你拥有的是一个JSON数组,将其解组为Go切片。建议创建一个Student结构,以便为学生建立一个干净且有意识的Go代码。

And in the template the {{range}} action sets the dot . to the current element, you can refer to it inside the {{range}} body simply as the dot ., so the student name will be .Name.

在模板中,{{range}}操作设置点。对于当前元素,您可以在{{range}}体内引用它作为点。,因此学生名称将为.Name。

Working code (try it on the Go Playground):

工作代码(在Go Playground上试试):

func main() {
    t := template.Must(template.New("").Parse(templ))
    var students []Student
    if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
        panic(err)
    }
    params := map[string]interface{}{"Students": students}
    if err := t.Execute(os.Stdout, params); err != nil {
        panic(nil)
    }
}

const jsondata = `[
  {
    "id": 1,
    "name": "Mary"
  },
  {
    "id": 2,
    "name": "John"
  }
]`

const templ = `<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>
        {{range .Students}}
        <td>{{.Name}}</td>                    
        {{end}}
 </TABLE>`

Output:

<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>

        <td>Mary</td>                    

        <td>John</td>                    

 </TABLE>

With a map

If you don't want to create and use a Student struct, you can still do it with a simple map whose type is map[string]interface{} which can represent any JSON object, but know that in this case you have to refer to students' names as .name as that is how it appears in the JSON text, and so lowercased "name" key will be used in the unmarshaled Go map:

如果您不想创建和使用Student结构,您仍然可以使用类型为map [string] interface {}的简单映射来实现它,它可以表示任何JSON对象,但是知道在这种情况下您必须引用将学生的名字命名为.name,就像它在JSON文本中的显示方式一样,因此在未编组的Go地图中将使用小写的“name”键:

func main() {
    t := template.Must(template.New("").Parse(templ))
    var students []map[string]interface{}
    if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
        panic(err)
    }
    params := map[string]interface{}{"Students": students}
    if err := t.Execute(os.Stdout, params); err != nil {
        panic(nil)
    }
}

const templ = `<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>
        {{range .Students}}
        <td>{{.name}}</td>                    
        {{end}}
 </TABLE>`

Output is the same. Try this variant on the Go Playground.

输出是一样的。在Go Playground上试试这个变种。

#1


1  

With a struct

What you have is a JSON array, unmarshal it into a Go slice. Recommended to create a Student struct to model your students to have a clean and conscious Go code.

你拥有的是一个JSON数组,将其解组为Go切片。建议创建一个Student结构,以便为学生建立一个干净且有意识的Go代码。

And in the template the {{range}} action sets the dot . to the current element, you can refer to it inside the {{range}} body simply as the dot ., so the student name will be .Name.

在模板中,{{range}}操作设置点。对于当前元素,您可以在{{range}}体内引用它作为点。,因此学生名称将为.Name。

Working code (try it on the Go Playground):

工作代码(在Go Playground上试试):

func main() {
    t := template.Must(template.New("").Parse(templ))
    var students []Student
    if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
        panic(err)
    }
    params := map[string]interface{}{"Students": students}
    if err := t.Execute(os.Stdout, params); err != nil {
        panic(nil)
    }
}

const jsondata = `[
  {
    "id": 1,
    "name": "Mary"
  },
  {
    "id": 2,
    "name": "John"
  }
]`

const templ = `<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>
        {{range .Students}}
        <td>{{.Name}}</td>                    
        {{end}}
 </TABLE>`

Output:

<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>

        <td>Mary</td>                    

        <td>John</td>                    

 </TABLE>

With a map

If you don't want to create and use a Student struct, you can still do it with a simple map whose type is map[string]interface{} which can represent any JSON object, but know that in this case you have to refer to students' names as .name as that is how it appears in the JSON text, and so lowercased "name" key will be used in the unmarshaled Go map:

如果您不想创建和使用Student结构,您仍然可以使用类型为map [string] interface {}的简单映射来实现它,它可以表示任何JSON对象,但是知道在这种情况下您必须引用将学生的名字命名为.name,就像它在JSON文本中的显示方式一样,因此在未编组的Go地图中将使用小写的“name”键:

func main() {
    t := template.Must(template.New("").Parse(templ))
    var students []map[string]interface{}
    if err := json.Unmarshal([]byte(jsondata), &students); err != nil {
        panic(err)
    }
    params := map[string]interface{}{"Students": students}
    if err := t.Execute(os.Stdout, params); err != nil {
        panic(nil)
    }
}

const templ = `<TABLE class= "myTable" >
        <tr class="headingTr">
            <td>Name</td>
        </tr>
        {{range .Students}}
        <td>{{.name}}</td>                    
        {{end}}
 </TABLE>`

Output is the same. Try this variant on the Go Playground.

输出是一样的。在Go Playground上试试这个变种。