gpt4 book ai didi

html - 转到调用 t.Execute 中的许多参数

转载 作者:数据小太阳 更新时间:2023-10-29 03:40:12 24 4
gpt4 key购买 nike

我正在尝试使用从数据库表中获取的值来呈现模板。问题是当我运行程序时出现错误。我不知道我做错了什么。

我开始创建一个结构:

type App struct{
Title string
Author string
Description string
}

我创建了一个函数来呈现模板:

   func render(w http.ResponseWriter, tmpl string, data map[string]interface{}){
tmpl = fmt.Sprintf("templates/%s", tmpl)
t, err := template.ParseFiles(tmpl)
if err != nil{
log.Print("template parsing error: ", err)
}
err = t.Execute(w, data)
if err != nil{
log.Print("template executing error: ", err)
}
}

然后,在这里我从数据库中获取应用程序并尝试将它们呈现为 html。

func myappsHandler(w http.ResponseWriter, r *http.Request){
db, err := sql.Open("postgres"," user=postgres dbname=lesson4 host=localhost password=1234 sslmode=disable")
if err != nil{
log.Fatal(err)
}
rows, err := db.Query(`SELECT title, author, description FROM apps
WHERE title ILIKE $1
OR author ILIKE $1
OR description ILIKE $1`)
defer rows.Close()

apps := []App{}
for rows.Next(){
b := App{}
err := rows.Scan(&b.Title, &b.Author, &b.Description)

if err != nil{
log.Fatal(err)
}
apps = append(apps, b)
}

render(w, "myapps.html", map[string]interface{}{"apps" : apps})

db.Close()
}

我的主要功能:

func main() {

http.HandleFunc("/myapps", myappsHandler)
http.ListenAndServe(":8080", nil)
}

这是 myapps.html

<html>
<body>
<table class="table">
<tr>
<th>Título</th>
<th>Imagen</th>
<th>Descripción</th>
</tr>
{{ range .}}
<tr>
<td>{{ .Title }}</td>
<td>{{ .Author }}</td>
<td>{{ .Description }}</td>
<td> <form action="/delete">
<p class="navbar-form navbar-right"><button type="submit" class="btn btn-danger">Borrar</button> </p>
</form></td>
</tr>
{{ end }}
</table>
</body>
</html>

最佳答案

您的render 函数接受一个http.ResponseWriter 和一个string。您正在尝试将 http.ResponseWriterstring []App 传递给它。

简短的回答是,您应该更改函数以接受可以传递给 ExecuteTemplatemap[string]interface。当您稍后想将不止一件事传递给模板时,这很有用。

func render(w http.ResponseWriter, tmpl string, data map[string]interface{}){
tmpl = fmt.Sprintf("templates/%s", tmpl)
t, err := template.ParseFiles(tmpl)
if err != nil{
log.Print("template parsing error: ", err)
}
// We pass our data map to the template
err = t.Execute(w, data)
if err != nil{
log.Print("template executing error: ", err)
}
}

... 并这样调用它:

    render(w, "myapps.html", map[string]interface{}{
"apps": apps
})

长答案是:

  • 您正在为每个请求建立一个新的数据库池。不好!创建一个全局池(好的;sql.DB 有锁)或通过将 *sql.DB 传递给您的处理程序。

  • 您正在根据每个请求重新解析您的模板。这是缓慢且低效的。根据 http://golang.org/doc/articles/wiki/#tmp_6 在启动时解析它们一次

  • 您可以通过编写 type M map[string]interface{}map[string]interface{} 编写一个快捷方式,这将允许您改为编写 render(w, "myapps.html", M{"apps": apps})

  • 您应该将您的数据库查询拆分成它自己的函数,以便您可以在别处重复使用它。

  • sqlx可以帮助您不必自己处理 rows.Scan() 事情 - 它是 database/sql 的一个很好的便利包装器。

已更新

我已经设法在我的机器上编译了您的代码(大部分),并且没有任何 panic 。我建议您阅读整个堆栈跟踪,包括 nil 指针引用/内存地址上方的位,这可能类似于“模板解析错误”(您的文件名是否正确?)。

http://play.golang.org/p/QZ65eP-Aln (我已经注释掉了数据库的东西)

需要修复您的模板以具有{{ range .apps }},但这不会成为 panic 的根源。

<html>
<body>
<table class="table">
<tr>
<th>Título</th>
<th>Imagen</th>
<th>Descripción</th>
</tr>
{{ range .apps }}
<tr>
<td>{{ .Title }}</td>
<td>{{ .Author }}</td>
<td>{{ .Description }}</td>
<td> <form action="/delete">
<p class="navbar-form navbar-right"><button type="submit" class="btn btn-danger">Borrar</button> </p>
</form></td>
</tr>
{{ end }}
</table>
</body>
</html>

关于html - 转到调用 t.Execute 中的许多参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24672762/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com