英文:
How to send an array of maps and iterate over it using gin-templating
问题
以下是一段工作代码的片段。我正在使用gin模板引擎。
c.HTML(200, "index", gin.H{
"title": "Welcome",
"students": map[int]map[string]string{1: {"PID": "1", "Name": "myName"}},
})
在index模板中,我有以下内容:
<TABLE class="myTable">
<tr class="headingTr">
<td>Name</td>
</tr>
{{range $student := .students}}
<td>{{$student.Name}}</td>
{{end}}
</TABLE>
如你所见,我在标题(map)中硬编码了students
的值。我希望从我构建的REST API中获取这些数据。我的REST API的响应是一个数组:
[
{
"id": 1,
"name": "Mary"
},
{
"id": 2,
"name": "John"
}
]
我可以将这个JSON响应解组为map[string]string
,而不是map[int]map[string]string
。我该如何将这个解组后的数据作为students
的参数值,并在index模板中对这个数组进行迭代?
英文:
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:
[
{
"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?
答案1
得分: 1
使用结构体
你现在有一个JSON数组,将其解组为Go切片。建议创建一个Student
结构体来模拟你的学生,以便编写干净和明确的Go代码。
在模板中,{{range}}
操作将点号.
设置为当前元素,你可以在{{range}}
体内直接使用点号.
来引用它,所以学生的姓名将是.Name
。
以下是可运行的代码(在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>`
输出结果:
<TABLE class="myTable">
<tr class="headingTr">
<td>Name</td>
</tr>
<td>Mary</td>
<td>John</td>
</TABLE>
使用映射
如果你不想创建和使用Student
结构体,你仍然可以使用一个简单的映射,其类型为map[string]interface{}
,它可以表示任何JSON对象。但是要知道,在这种情况下,你必须将学生的姓名引用为.name
,因为它在JSON文本中是这样出现的,因此小写的"name"
键将在解组后的Go映射中使用:
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>`
输出结果与前面相同。在Go Playground上尝试这个变体。
英文:
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.
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
.
Working code (try it on the 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:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论