Не удается получить доступ к данным из html/template Golang

У меня есть три объединенных шаблона. base.html, menu.html, users.html. Но когда я выполняю эти шаблоны, я могу получить доступ к данным контекста только из base.html.

Вот мой обработчик:

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)
 }
}

Это то, что я хочу показать в шаблоне пользователей

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

Примечание. Я могу получить доступ к "{{.Title}}", который используется в шаблоне base.html.


person Matias graña    schedule 06.03.2017    source источник


Ответы (1)


Во-первых, вы должны проверить ошибки, возвращаемые методом Template.ParseFiles(). Вы сохраняете возвращенную ошибку, но проверяете ее только в конце (и к тому времени она перезаписывается раза 3).

Далее, никогда не анализируйте шаблоны в обработчике запросов, это отнимает слишком много времени и ресурсов. Сделайте это один раз при запуске (или по первому требованию). Подробнее см. При использовании пакета шаблонов создание динамической веб-страницы для клиента в golang занимает слишком много времени.

Далее вы можете парсить сразу несколько файлов, просто перечислите все при переходе к Template.ParseFiles()< /a> функция (есть метод и функция).

Помните, что Template.Execute() выполняет только один (именованный) шаблон. У вас есть 3 связанных шаблона, но только "base.html" шаблона выполняется вашим кодом. Чтобы выполнить определенный именованный шаблон, используйте Template.ExecuteTemplate(). Подробнее см. в разделе Сообщение Golang, какой шаблон выполнять первым.

Сначала вы должны определить структуру ваших шаблонов, решить, какие шаблоны включают в себя другие, и выполнить шаблон "оболочки" (используя Template.ExecuteTemplate()). Когда вы выполняете шаблон, который вызывает/включает другой шаблон, у вас есть возможность указать, какое значение (данные) вам передать для его выполнения. Когда вы пишете {{template "something" .}}, это означает, что вы хотите передать значение, на которое в данный момент указывает точка, для выполнения шаблона с именем "something". Узнайте больше об этом: конвейеры механизма шаблонов golang.

Чтобы узнать больше о ассоциации шаблонов и внутренних компонентах, прочитайте этот ответ: имя шаблона Go.

Итак, в вашем случае я бы предположил, что "base.html" является оболочкой, внешним шаблоном, который включает "menu.html" и "users.html". Таким образом, "base.html" должен содержать строки, подобные этой:

{{template "menu.html" .}}

{{template "users.html" .}}

Вышеупомянутые строки будут вызывать и включать результаты упомянутых шаблонов, передавая на их выполнение данные, которые были переданы "base.html" (если точка не была изменена).

Проанализируйте файлы, используя template.ParseFiles() функцию (не метод ) как это:

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
    }
}

И выполните это в своем обработчике следующим образом:

err := t.ExecuteTemplate(w, "base.html", context)
person icza    schedule 06.03.2017
comment
Спасибо за ответ. Я не поставил точечный конвейер для передачи данных - person Matias graña; 06.03.2017