简体   繁体   中英

Go html template access struct fields inside range

Given below struct, I want to access field2 while iterating over field1 data in html. How do I do this?

var MyPageData struct {
      field1 []Foo
      field2 map[string]Bar
}

I tried: Inside Handler function:

err := myPageTemplate.Execute(w,MyPageData{ field1: field1Slice, field2 : myMapData})

Template:

     {{ range $index, $fooInstance := .field1}} 
        <tr>
            <td>{{$fooInstance.Name}}</td> //This prints the Name value
            <td>{{ index .$field2 "myKey".Name }}</td>

How do I access field2 above and specify a key value to retrieve Bar instance?

UPDATE Adding Foo and Bar structs

type Foo2 struct {
    Name string
    Id  int 
}


type Foo struct {
    Name string
    element Foo2
}

type Bar struct {
    Name string
}

No matter what the value of the pipeline is (which is denoted by the dot . in the template), you can use the $ to refer to the data value you passed to Template.Execute() . The {{range}} action iterates over the elements and it sets the pipeline ( . ) to the current item, so . always denotes the current item, $ is absolutely refers to the "top level" data passed to Template.Execute() .

This is documented in text/template :

When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.

Also note that you have to export struct fields to be available in templates. So change your MyPageData type to:

type MyPageData struct {
    Field1 []Foo
    Field2 map[string]Bar
}

Also note that you can simply access map elements using the . operator. So you can access the value of the Field2 map associated with the "myKey" key like this, inside the {{range}} action too:

{{$.Field2.myKey}}

See this simple example:

type MyPageData struct {
    Field1 []Foo
    Field2 map[string]Bar
}

type Foo struct {
    Name string
}

type Bar struct {
    Name string
}

func main() {
    t := template.Must(template.New("").Parse(templ))
    mpd := MyPageData{
        Field1: []Foo{{"First"}, {"Second"}},
        Field2: map[string]Bar{"myKey": {"MyValue"}},
    }
    t.Execute(os.Stdout, mpd)
}

const templ = `{{range $idx, $foo := .Field1}}{{$.Field2.myKey}} {{$idx}} - {{$foo.Name}}
{{end}}`

Output (try it on the Go Playground ):

{MyValue} 0 - First
{MyValue} 1 - Second

Also note that insdie the {{range}} instead of $foo.Name you can simply use {{.Name}} as the dot . denotes $foo , the current item.

If you want to lookup a value from Field2 with a dynamic key, you do need to use the {{index}} action. For example if you want the value associated with the key being $foo.Name :

{{index $.Field2 $foo.Name}}

Or short:

{{index $.Field2 .Name}}

And going forward, if the value associated with the key is a struct for example, and you only need a field of this struct, let's say Id , you can use parenthesis:

{{(index $.Field2 .Name).Id}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM