问题描述
我正在为一个学校项目在 Go 中构建一个简单的论坛,并将数据结构传递给模板以显示子论坛中的所有帖子。我传递给模板的数据是这样的:
type Data struct {
ID int // ID of the subforum
User User // logged-in user
Posts []Post // all the posts of the subforum
}
Data 结构中的 Post 结构是这样的:
type Post struct {
ID int
Title string
Content string
Date time.Time
[...]
Author User
Comments []Comment
}
Comment 结构类似于 Post 结构。当我显示所有帖子的列表时,我还想显示回复数量和最后回复的日期/时间。
{{range .Posts}}
<p>Replies: {{ len .Comments }}</p>
{{ end }}
...但我似乎无法理解获取 Comments 数组最后一个元素的日期。我知道您可以使用 index 关键字和值 '0' 获取第一个元素,但我不能在模板中使用 (len .Comments -1)获取最后一个元素,因为 '-' 是一个禁止字符。我可能只需要创建第二个函数,以便从我的 sqlite 数据库中按降序对我的评论进行排序,但我想知道是否有一种简单的方法来处理 Go 模板中的索引。
谢谢。
解决方法
使用 Go 模板没有一种干净的方法可以做到这一点,但这是一种解决方法 here。一个更简单的解决方法是在将结构传递给模板程序之前将最后一项添加到结构中。您正在做的是将复杂的逻辑从模板中移出(无论如何,模板并非设计用于执行此操作)并移至 Go 代码中。
type Post struct {
....
Comments []Comment
LastComment Comment
}
然后在你的模板中,做
{{ .LastComment }}
,
您可以在模板中使用自定义函数来获取最后一个元素:
fmap := template.FuncMap{
"lastElem": func(comments []Comment) Comment {
return comments[len(comments)-1]
},}
tmpl,err := template.New("tmpl").Funcs(fmap).Parse(tpl)
然后在您的模板中使用它:
{{range .Posts}}
<p>Replies: {{ lastElem .Comments }}</p>
{{ end }}