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)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题