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 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度