英文:
Go template ranging over struct of structs
问题
我正在尝试遍历一个包含两个结构体的结构体列表。在填充结构体的数据方面我没有问题,但当我尝试将其渲染到HTML时出现问题,无法显示任何内容。
这是我第一个Go Web项目,我正在为一家小企业开发一个销售汽车的网站。我的数据库设计为1..M的Cars到Pics关系。所以在主要的汽车页面上,我只想加载一张带有汽车详细信息的图片。我尝试使用map来实现这一点,但当我想要打印出与正确汽车详细信息对应的一张图片时,遇到了问题。所以我想使用第三个结构体,从每个ID中提取一张图片。
type Car struct {
Id int
Year, Make, Model, Price string
}
type Pics struct {
Id int
Path string
}
type CarDetail struct {
Cars Car
Pic Pics
}
func cars(w http.ResponseWriter, r *http.Request){
//加载数据库中的所有汽车
cars := loadCars()
carDetails := make([]CarDetail,0)
carIds := make([]int,len(cars))
for i := 0; i < len(cars); i++{
//获取数据库中的所有汽车ID
carIds[i] = getCarID(cars[i])
photoPath := loadSinglePhoto(carIds[i]) //现在有了单张照片
n := CarDetail{Cars:cars[i],Pic:photoPath}
carDetails = append(carDetails, n)
}
fmt.Println(carDetails) //以我想要的方式获取汽车详细信息
tpl.ExecuteTemplate(w, "cars", &carDetails)
}
在传入结构体之前的打印语句给出了我想要的信息。
[{{20 2009 Honda Accord 5000} {20 public/pics/questionMark.jpg}} {{21 2009 Acura TLX 14000} {21 public/pics/kia.png}} {{22 2015 Kia Sportage 34000} {22 public/pics/kia.png}}]
现在当我尝试在HTML中渲染它时:
{{range .}}
<h3>{{.Cars.Make}} - {{.Cars.Model}} - {{.Cars.Year}}</h3>
<img src="{{.Pic.Path}}" id="{{.Pic.Id}}">
{{end}}
请随意批评我的代码或提出其他建议。提前谢谢!
英文:
I'm attempting to range over a list of a struct consisting of 2 structs inside of it. I have no problem filling the data correctly in the struct, the problem is when I try to render it into the HTML. I can't get anything to display.
This is my first go web project and I'm working on a website to sell cars for a small business. My Database is designed as a 1..M of Cars to Pics. So on the main car page. I want to just load 1 pic with the details of the car. I tried using a map for this but I ran into an issue when I wanted to print out just 1 picture to go with the correct car details on the common ID. So I figured using a third struct that I pull out one pic for each ID would work.
type Car struct {
Id int
Year, Make, Model, Price string
}
type Pics struct {
Id int
Path string
}
type CarDetail struct {
Cars Car
Pic Pics
}
func cars(w http.ResponseWriter, r *http.Request){
//loads all the cars in the database
cars := loadCars()
carDetails := make([]CarDetail,0)
carIds := make([]int,len(cars))
for i := 0; i < len(cars); i++{
//gets all the car IDs in the db
carIds[i] = getCarID(cars[i])
photoPath := loadSinglePhoto(carIds[i]) //now have the single photo
n := CarDetail{Cars:cars[i],Pic:photoPath}
carDetails = append(carDetails, n)
}
fmt.Println(carDetails) //getting car details the way I want
tpl.ExecuteTemplate(w, "cars", &carDetails)
}
The print statement right before I pass in the struct gives me the information the way I intended.
[{{20 2009 Honda Accord 5000} {20 public/pics/questionMark.jpg}} {{21 2009 Acura TLX 14000} {21 public/pics/kia.png}} {{22 2015 Kia Sportage 34000} {22 public/pics/kia.png}}]
Now when I try to render it in the html
{{range .}}
<h3>{{.Cars.Make}} - {{.Cars.Model}} - {{.Cars.Year}}</h3>
<img src="{{.Pic.Path}}" id="{{.Pic.Id}}">
{{end}}
Feel free to be critical of my code or suggest another way. Thank you in advance!
答案1
得分: 1
一些一般性的评论:
- 你的命名有点误导性:Pics只保存一张图片,而不是多张(不是一个数组或映射);CarDetail.Cars也是同样的情况。
- 不知道你使用的是哪个数据库,我建议构建一个查询,返回汽车和(主要)图片,因为通过每辆汽车单独查找图片的性能不佳。
- 我建议将模板存储为具有特定扩展名的文件(例如 "cars.gohtml"),然后使用 template.ParseGlob("templates/*.gohtml")。
除此之外,代码应该可以正常工作,你可以在这里看到一个稍微重构的可工作示例:
https://play.golang.org/p/CPnad9FxaB
那么在你自己的代码中到底出了什么问题?
英文:
Some remarks on a general level:
- Your naming is a bit misleading: Pics holds only a single picture, not many (not an array or map); same applies to CarDetail.Cars
- Not knowing which database you are using I would recommend to build a query returning both cars and (primary) picture, as looking the pics up by every single car will not perform well
- I would recommend storing the templates as files in a sub-folder with specific extensions (e.g. "cars.gohtml") and then use template.ParseGlob("templates/*.gohtml")
Apart from that it should work, see a slightly refactored working example here:
https://play.golang.org/p/CPnad9FxaB
So what exactly is going wrong in your own code?
答案2
得分: 1
所以我找到了罪魁祸首。奇怪的是,之前注释掉的HTML代码导致模板无法渲染。我不确定原因。
<!--
<h1>Your Pictures:</h1>
{{range .Pics}}
<img class="insertedPics" src="{{.Path}}" alt="pic" id="{{.Id}}"
height="500px" width="500px">
{{end}}
{{range .Cars}}
<h3>{{.Make}} - {{.Model}} - {{.Year}} </h3>
{{end}}
<img src="{{.Pic.Path}}" alt="car pic" id="{{.Car.Id}}" height="600px" width="600px">
--> <-- 一旦我删除了这部分,一切都正常工作了。
{{range .}}
<h3>{{.C.Make}} - {{.C.Model}}</h3>
<img src="{{.P.Path}}" alt="some pic" height="500px" width="500px"
style="">
{{end}}
感谢您的帮助和建议!
英文:
So I found the culprit. Strangely enough some commented out HTML code from earlier was causing the template not to be rendered. I'm not sure why.
<!--
<h1>Your Pictures:</h1>
{{range .Pics}}
<img class="insertedPics" src="{{.Path}}" alt="pic" id="{{.Id}}"
height="500px" width="500px">
{{end}}
{{range .Cars}}
<h3>{{.Make}} - {{.Model}} - {{.Year}} </h3>
{{end}}
<img src="{{.Pic.Path}}" alt="car pic" id="{{.Car.Id}}" height="600px" width="600px">
--> <-- Once I removed this, everything worked fine.
{{range .}}
<h3>{{.C.Make}} - {{.C.Model}}</h3>
<img src="{{.P.Path}}" alt="some pic" height="500px" width="500px"
style="">
{{end}}
Thank you for the help and suggestions!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论