Как мне получить доступ к полю объекта по переменной в шаблоне?

У меня есть вложенный цикл:

{{$columns := .columns}}
{{range $dx := .dataList}}
    {{range $c := $columns}}
        {{index $dx $c}}
    {{end}}
{{end}}

dataList - это массив моделей orm. С ID, Title поля, то columns это []string переменная содержит все имена полей модели orm, такие как ID, Title,

type AdFile struct {
    ID      uint `gorm:"primary_key"`
    Title   string
}

Я пробовал с {{(index .listData 0).Title}} и это работает.

Но если я хочу получить доступ $dx.Title, $dx.ID.... с Title, ID как переменные, но это не работает. я пробовал $dx[$c],

Можно легко добиться того же с Python

for i in list_data
    tr
        for p in columns
            td=i[p]

1 ответ

Решение

Чтобы получить доступ к значениям полей структуры, заданной их именами, вам нужна помощь reflect пакет. Это можно сделать так:

v := AdFile{ID:1, Title: "T1"} // A struct value
name := "ID"                   // field name

fieldValue := reflect.ValueOf(v).FieldByName(name).Interface()

Поскольку это код Go, вы не можете встраивать его в шаблоны. Но вы можете зарегистрировать пользовательские функции с Template.Funcs() метод, который может быть вызван из шаблонов.

Итак, давайте сделаем это: оберните эту функцию в функцию и зарегистрируйте ее по имени "Field" так что мы можем вызвать это из нашего шаблона.

func main() {
    t := template.Must(template.New("").Funcs(template.FuncMap{
        "Field": func(v interface{}, name string) interface{} {
            return reflect.ValueOf(v).FieldByName(name).Interface()
        },
    }).Parse(templ))

    m := map[string]interface{}{
        "columns": []string{"ID", "Title"},
        "dataList": []AdFile{
            {ID: 1, Title: "Title1"},
            {ID: 2, Title: "Title2"},
        },
    }

    if err := t.Execute(os.Stdout, m); err != nil {
        panic(err)
    }

}

const templ = `{{$columns := .columns}}
{{range $dx := .dataList}}
    {{range $c := $columns}}
        {{- Field $dx $c }}
    {{end}}
{{end}}`

Вывод вышеупомянутого приложения (попробуйте на Go Playground):

1
Title1


2
Title2

Примечание: проверка ошибок в зарегистрированных "Field" функция. Вы можете улучшить его, чтобы вернуться nil если заданное имя поля недопустимо или возвращает ошибку, которая обрабатывается механизмом шаблонов (в этом случае выполнение шаблона будет прервано с возвращаемой ошибкой).

Другие вопросы по тегам