Go 模板中的嵌套循环
Nested loops in Go templates
编码员。
我需要在 go 模板中渲染嵌套结构数据。我想知道是否可以在 .gohtml
模板文件中处理嵌套循环。
这是我的 .gohtml
代码:
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
{{range $city := .}}
<li>
name: {{$city.name}}
hotels:
<ul>
{{range $hotel := $city.hotels}}
<li>
name: {{$hotel.name}}
address: {{$hotel.address}}
zip: {{$hotel.zip}}
</li>
{{end}}
</ul>
</li>
{{end}}
</ul>
</body>
</html>
这里是main.go
代码:
package main
import (
"os"
"text/template"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.New("").ParseGlob("./*.gohtml"))
}
func main() {
type hotel struct {
name string
address string
city string
zip int
}
type city struct {
name string
hotels []hotel
}
type region struct {
cities []city
}
hotel1 := hotel{
"Lambda",
"Street 19",
"Some city",
65530,
}
hotel2 := hotel{
"Black Sea",
"Street 21",
"Some city",
65543,
}
hotel3 := hotel{
"Blue Sea",
"Street 15",
"Some city",
54400,
}
hotel4 := hotel{
"Yellow Submarine",
"The Beatles Square",
"Some city",
54401,
}
hotel5 := hotel{
"LolKek",
"Cheburek",
"Some city",
14213,
}
city1 := city{
"Some city",
[]hotel{hotel1, hotel2},
}
city2 := city{
"Some city",
[]hotel{hotel3, hotel4},
}
city3 := city{
"Some city",
[]hotel{hotel5},
}
someRegion := region{
[]city{city1, city2, city3},
}
tpl.ExecuteTemplate(os.Stdout, "tpl.gohtml", someRegion)
}
go run main.go
时终端没有报错,但不明白为什么输出是这样的:
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
为什么被剪掉了?
您没有看到任何错误,因为您没有检查错误,而是忽略了错误。
Template.ExecuteTemplate()
returns 错误,检查一下:
if err := tpl.ExecuteTemplate(os.Stdout, "tpl.gohtml", someRegion); err != nil {
fmt.Println(err)
}
这将输出:
template: :9:29: executing "" at <.>: range can't iterate over {[{Some city [{Lambda Street 19 Some city 65530} {Black Sea Street 21 Some city 65543}]} {Some city [{Blue Sea Street 15 Some city 54400} {Yellow Submarine The Beatles Square Some city 54401}]} {Some city [{LolKek Cheburek Some city 14213}]}]}
错误很明显:您传递了一个用于执行的结构,然后您尝试对其进行范围调整。你不能。切片范围:
{{range $city := .cities}}
这当然行不通:您必须导出结构字段才能在模板中访问它。
type region struct {
Cities []city
}
在模板中:
{{range $city := .Cities}}
您还必须导出其他结构字段:
type hotel struct {
Name string
Address string
City string
Zip int
}
type city struct {
Name string
Hotels []hotel
}
经过这些更改后,它将工作并输出(在 Go Playground 上尝试):
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
<li>
name: Some city
hotels:
<ul>
<li>
name: Lambda
address: Street 19
zip: 65530
</li>
<li>
name: Black Sea
address: Street 21
zip: 65543
</li>
</ul>
</li>
<li>
name: Some city
hotels:
<ul>
<li>
name: Blue Sea
address: Street 15
zip: 54400
</li>
<li>
name: Yellow Submarine
address: The Beatles Square
zip: 54401
</li>
</ul>
</li>
<li>
name: Some city
hotels:
<ul>
<li>
name: LolKek
address: Cheburek
zip: 14213
</li>
</ul>
</li>
</ul>
</body>
</html>
编码员。
我需要在 go 模板中渲染嵌套结构数据。我想知道是否可以在 .gohtml
模板文件中处理嵌套循环。
这是我的 .gohtml
代码:
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
{{range $city := .}}
<li>
name: {{$city.name}}
hotels:
<ul>
{{range $hotel := $city.hotels}}
<li>
name: {{$hotel.name}}
address: {{$hotel.address}}
zip: {{$hotel.zip}}
</li>
{{end}}
</ul>
</li>
{{end}}
</ul>
</body>
</html>
这里是main.go
代码:
package main
import (
"os"
"text/template"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.New("").ParseGlob("./*.gohtml"))
}
func main() {
type hotel struct {
name string
address string
city string
zip int
}
type city struct {
name string
hotels []hotel
}
type region struct {
cities []city
}
hotel1 := hotel{
"Lambda",
"Street 19",
"Some city",
65530,
}
hotel2 := hotel{
"Black Sea",
"Street 21",
"Some city",
65543,
}
hotel3 := hotel{
"Blue Sea",
"Street 15",
"Some city",
54400,
}
hotel4 := hotel{
"Yellow Submarine",
"The Beatles Square",
"Some city",
54401,
}
hotel5 := hotel{
"LolKek",
"Cheburek",
"Some city",
14213,
}
city1 := city{
"Some city",
[]hotel{hotel1, hotel2},
}
city2 := city{
"Some city",
[]hotel{hotel3, hotel4},
}
city3 := city{
"Some city",
[]hotel{hotel5},
}
someRegion := region{
[]city{city1, city2, city3},
}
tpl.ExecuteTemplate(os.Stdout, "tpl.gohtml", someRegion)
}
go run main.go
时终端没有报错,但不明白为什么输出是这样的:
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
为什么被剪掉了?
您没有看到任何错误,因为您没有检查错误,而是忽略了错误。
Template.ExecuteTemplate()
returns 错误,检查一下:
if err := tpl.ExecuteTemplate(os.Stdout, "tpl.gohtml", someRegion); err != nil {
fmt.Println(err)
}
这将输出:
template: :9:29: executing "" at <.>: range can't iterate over {[{Some city [{Lambda Street 19 Some city 65530} {Black Sea Street 21 Some city 65543}]} {Some city [{Blue Sea Street 15 Some city 54400} {Yellow Submarine The Beatles Square Some city 54401}]} {Some city [{LolKek Cheburek Some city 14213}]}]}
错误很明显:您传递了一个用于执行的结构,然后您尝试对其进行范围调整。你不能。切片范围:
{{range $city := .cities}}
这当然行不通:您必须导出结构字段才能在模板中访问它。
type region struct {
Cities []city
}
在模板中:
{{range $city := .Cities}}
您还必须导出其他结构字段:
type hotel struct {
Name string
Address string
City string
Zip int
}
type city struct {
Name string
Hotels []hotel
}
经过这些更改后,它将工作并输出(在 Go Playground 上尝试):
<!DOCTYPE html>
<html>
<head>
<meta charser="utf-8" />
<title>Go templates</title>
</head>
<body>
<ul>
<li>
name: Some city
hotels:
<ul>
<li>
name: Lambda
address: Street 19
zip: 65530
</li>
<li>
name: Black Sea
address: Street 21
zip: 65543
</li>
</ul>
</li>
<li>
name: Some city
hotels:
<ul>
<li>
name: Blue Sea
address: Street 15
zip: 54400
</li>
<li>
name: Yellow Submarine
address: The Beatles Square
zip: 54401
</li>
</ul>
</li>
<li>
name: Some city
hotels:
<ul>
<li>
name: LolKek
address: Cheburek
zip: 14213
</li>
</ul>
</li>
</ul>
</body>
</html>