dpqmu84646 2017-03-06 12:43
浏览 99
已采纳

无法从html / template Golang访问数据

I have three concatenated templates. base.html, menu.html, users.html. But when I execute these templates I can access data of context only from base.html.

Here is my Handler:

func HandlerUser(res http.ResponseWriter, req *http.Request){
if req.Method == "GET" {
    context := Context{Title: "Users"}
    users,err:= GetUser(0)
    context.Data=map[string]interface{}{
        "users": users,
    }
    fmt.Println(context.Data)
    t,err := template.ParseFiles("public/base.html")
    t,err = t.ParseFiles("public/menu.html")
    t,err = t.ParseFiles("public/users.html")
    err = t.Execute(res,context)
    fmt.Println(err)
 }
}

This is what I want to show in users template

{{ range $user := index .Data "users" }}
<tr id="user-{{ .Id }}">
    <td id="cellId" >{{ $user.Id }}</td>
    <td id="cellUserName" >{{ $user.UserName }}</td>
</tr>
{{ end }}

Note: I can access "{{.Title}}" that is used in base.html template.

  • 写回答

1条回答 默认 最新

  • dongmao7195 2017-03-06 13:07
    关注

    First, you should check errors returned by the Template.ParseFiles() method. You store the returned error, but you only check it at the end (and by then it is overwritten like 3 times).

    Next, never parse templates in the request handler, it's too time consuming and resource wasting. Do it once at startup (or on first demand). For details see It takes too much time when using "template" package to generate a dynamic web page to client in golang.

    Next, you can parse multiple files at once, just enumerate all when passing to the Template.ParseFiles() function (there is a method and a function).

    Know that Template.Execute() only executes a single (named) template. You have 3 associated templates, but only the "base.html" template is executed by your code. To execute a specific, named template, use Template.ExecuteTemplate(). For details, see Telling Golang which template to execute first.

    First you should define a structure of your templates, decide which templates include others, and execute the "wrapper" template (using Template.ExecuteTemplate()). When you execute a template that invokes / includes another template, you have the possibility to tell what value (data) you what to pass to its execution. When you write {{template "something" .}}, that means you want to pass the value currently pointed by dot to the execution of the template named "something". Read more about this: golang template engine pipelines.

    To learn more about template association and internals, read this answer: Go template name.

    So in your case I would imagine that "base.html" is the wrapper, outer template, which includes "menu.html" and "users.html". So "base.html" should contain lines similar to this:

    {{template "menu.html" .}}
    
    {{template "users.html" .}}
    

    The above lines will invoke and include the results of the mentioned templates, passing the data to their execution that was passed to "base.html" (if dot was not changed).

    Parse the files using the template.ParseFiles() function (not method) like this:

    var t *template.Template
    
    func init() {
        var err error
        t, err = template.ParseFiles(
            "public/base.html", "public/menu.html", "public/users.html")
        if err != nil {
            panic(err) // handle error
        }
    }
    

    And execute it like this in your handler:

    err := t.ExecuteTemplate(w, "base.html", context)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 有偿求易语言word文档取doc和docx页数方法或模块
  • ¥15 找能接spark如图片的,可议价
  • ¥15 关于#单片机#的问题,请各位专家解答!
  • ¥15 博通raid 的写入速度很高也很低
  • ¥15 目标计数模型训练过程中的问题
  • ¥100 Acess连接SQL 数据库后 不能用中文筛选
  • ¥15 用友U9Cloud的webapi
  • ¥20 电脑拓展屏桌面被莫名遮挡
  • ¥20 ensp,用局域网解决
  • ¥15 Python语言实验