Go模板遍历结构体中的结构体。

huangapple go评论91阅读模式
英文:

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 &lt; 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, &quot;cars&quot;, &amp;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 .}}
  &lt;h3&gt;{{.Cars.Make}} - {{.Cars.Model}} - {{.Cars.Year}}&lt;/h3&gt;
  &lt;img src=&quot;{{.Pic.Path}}&quot; id=&quot;{{.Pic.Id}}&quot;&gt;
{{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.

&lt;!--

&lt;h1&gt;Your Pictures:&lt;/h1&gt;
{{range .Pics}}
&lt;img class=&quot;insertedPics&quot; src=&quot;{{.Path}}&quot; alt=&quot;pic&quot; id=&quot;{{.Id}}&quot; 
height=&quot;500px&quot; width=&quot;500px&quot;&gt;
{{end}}

{{range .Cars}}
&lt;h3&gt;{{.Make}} - {{.Model}} - {{.Year}} &lt;/h3&gt;
{{end}}

&lt;img src=&quot;{{.Pic.Path}}&quot; alt=&quot;car pic&quot; id=&quot;{{.Car.Id}}&quot; height=&quot;600px&quot; width=&quot;600px&quot;&gt;

--&gt;        &lt;-- Once I removed this, everything worked fine.

{{range .}}
&lt;h3&gt;{{.C.Make}} - {{.C.Model}}&lt;/h3&gt;
&lt;img src=&quot;{{.P.Path}}&quot; alt=&quot;some pic&quot; height=&quot;500px&quot; width=&quot;500px&quot; 
style=&quot;&quot;&gt;
{{end}}

Thank you for the help and suggestions!

huangapple
  • 本文由 发表于 2017年7月19日 09:45:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/45179681.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定