Golang模板学习过程中遇到的问题
Golang模板学习过程中遇到的问题 我是Go语言的新手,但很享受学习过程。下面的代码生成了一个HTML表格的主体部分:
{{define "table"}}
[table class="w3-table w3-striped"]
[thead]
[tr class="w3-yellow"]
[th]Created[/th]
[th>Todo[/th]
[th>Reminder[/th]
[/tr]
[/thead]
[tbody]
{{with .}} {{range .}}
[tr onclick="console.log('row clicked')"]
[td]{{.Datecreated}}[/td]
[td]{{.Todo}}[/td]
[td]{{.Datereminder}}[/td]
[td style="display: none"]{{.ID}}[/td]
[/tr]
{{end}} {{end}}
[/tbody]
[/table>
{{end}}
如果我将生成的HTML输出到os.StdOut,表格主体是存在的。我把生成的代码放到一个文件中,在Chrome里运行,显示正常。然而,当我使用Chrome访问localhost:3000时,页面中唯一缺失的部分就是表格主体,它是空的。我使用的是Content-Type: text/html。
这让我很困惑,任何帮助都将不胜感激。
抱歉HTML代码的呈现方式有问题,我得再读一遍说明。
更多关于Golang模板学习过程中遇到的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
这是一个典型的Go模板执行问题。问题很可能出在模板执行时传递的数据结构上。让我分析一下你的代码:
// 问题分析:
// 1. 你的模板使用了 {{with .}} {{range .}} 这意味着期望传入一个可迭代的数据结构
// 2. 如果表格主体为空,很可能是传入的数据为nil或空切片
// 正确的模板使用示例:
package main
import (
"html/template"
"net/http"
"os"
)
type TodoItem struct {
ID int
Datecreated string
Todo string
Datereminder string
}
func main() {
// 示例1:直接输出到stdout(你的测试方式)
tmpl := template.Must(template.New("table").Parse(`{{define "table"}}
<table class="w3-table w3-striped">
<thead>
<tr class="w3-yellow">
<th>Created</th>
<th>Todo</th>
<th>Reminder</th>
</tr>
</thead>
<tbody>
{{with .}}{{range .}}
<tr onclick="console.log('row clicked')">
<td>{{.Datecreated}}</td>
<td>{{.Todo}}</td>
<td>{{.Datereminder}}</td>
<td style="display: none">{{.ID}}</td>
</tr>
{{end}}{{end}}
</tbody>
</table>
{{end}}`))
// 测试数据
data := []TodoItem{
{ID: 1, Datecreated: "2023-01-01", Todo: "学习Go", Datereminder: "2023-12-31"},
{ID: 2, Datecreated: "2023-01-02", Todo: "学习模板", Datereminder: "2023-12-31"},
}
// 输出到stdout - 这会正常工作
tmpl.ExecuteTemplate(os.Stdout, "table", data)
// 示例2:HTTP服务器中的常见问题
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// 常见错误1:传递了nil数据
// tmpl.ExecuteTemplate(w, "table", nil) // 这会导致表格为空
// 常见错误2:传递了错误的数据结构
// tmpl.ExecuteTemplate(w, "table", TodoItem{}) // 这也会导致表格为空
// 正确的方式:传递切片数据
tmpl.ExecuteTemplate(w, "table", data)
})
http.ListenAndServe(":3000", nil)
}
// 调试建议:在HTTP处理器中添加日志
func handler(w http.ResponseWriter, r *http.Request) {
// 检查数据
var todos []TodoItem
// ... 从数据库或其他来源获取数据
// 添加调试日志
fmt.Printf("数据长度: %d\n", len(todos))
if len(todos) == 0 {
fmt.Println("警告: 数据切片为空")
}
// 确保Content-Type正确设置
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// 执行模板
err := tmpl.ExecuteTemplate(w, "table", todos)
if err != nil {
fmt.Printf("模板执行错误: %v\n", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
关键点:
- 确保传递给模板的数据是
[]TodoItem类型的切片,而不是单个结构体 - 检查数据源是否真的返回了数据
- 在HTTP处理器中添加错误处理和日志来调试
- 确保Content-Type正确设置为
text/html; charset=utf-8
最常见的错误是数据库查询返回空结果或nil,导致模板中的 {{with .}} 条件不满足。

