2017-06-24 9 views
3

テンプレートに渡すデータには、2つの変数TypeRes.Typeがあります。私の選択フィールドのオプションをあらかじめ選択するために比較したいです。それは"FindAllString"オプションを選択してくださいGoテンプレート内の2つの変数を比較

package main 

import (
    "bufio" 
    "bytes" 
    "html/template" 
    "log" 
) 

type Result struct{ Type string } 

func main() { 
    types := map[string]string{ 
     "FindAllString":  "FindAllString", 
     "FindString":   "FindString", 
     "FindStringSubmatch": "FindStringSubmatch", 
    } 
    res := &Result{Type: "findAllString"} 

    templateString := ` 
    <select name="type"> 
     {{ range $key,$value := .Types }} 
      {{ if eq $key .Res.Type }} 
       <option value="{{$key}}" selected>{{$value}}</option> 
      {{ else }} 
       <option value="{{$key}}">{{$value}}</option> 
      {{ end }} 
     {{ end }} 
    </select>` 
    t, err := template.New("index").Parse(templateString) 
    if err != nil { 
     panic(err) 
    } 
    var b bytes.Buffer 
    writer := bufio.NewWriter(&b) 
    err = t.Execute(writer, struct { 
     Types map[string]string 
     Res *Result 
    }{types, res}) 
    if err != nil { 
     panic(err) 
    } 
    writer.Flush() 
    log.Println(b.String()) 
} 

が、私はちょうどそれが動作する2つの通常の文字列を比較するとそれだけでエラーに

panic: template: index:4:21: executing "index" at <.Res.Type>: can't evaluate field Res in type string 

goroutine 1 [running]: 
panic(0x53f6e0, 0xc4200144c0) 
    /usr/local/go/src/runtime/panic.go:500 +0x1a1 
main.main() 
    /home/tobias/ngo/src/github.com/gamingcoder/tmp/main.go:41 +0x523 
exit status 2 

を生成します。私は、この簡易版を作成している私の問題を説明するために

私はこれを行うための愚かな方法があるかどうかを知りたい。私はあなたがテンプレートに関数を追加できることを見てきましたが、私はこれのためのより簡単な方法が必要であると感じています。

答えて

2

ループ変数($keyおよび$value)を使用しても、アクションによってドット(.)が変更(設定)されるという問題があります。 {{range}}の内部では、ドットは現在の要素に設定されます。

そして{{range}}の内側にあなたが書く:によって示さstring値(現在の要素のないResフィールドやメソッドがないため

{{ if eq $key .Res.Type }} 

あなたのループ内の値がstring値、.Res.Typeなのでは、エラーになりますドット.)。

ループ値を参照しますが、PARAMにテンプレートの実行に渡さないように$記号を使用してください:あなたが持っているように、

{{ if eq $key $.Res.Type }} 

これは動作しますが、あなたに所望の出力を与えることはありませんタイプミス:

:あなたの typesマップとして Result

res := &Result{Type: "findAllString"} 

使用大文字も大文字と値が含まれていますこれにより

あなたは、所望の出力(Go Playground上でそれを試してみてください)取得:また、テストのためのことに注意して

{{range $key, $value := .Types}} 
    <option value="{{$key}}"{{if eq $key $.Res.Type}} selected{{end}}>{{.}}</option> 
{{end}} 

2009/11/10 23:00:00 
    <select name="type"> 
       <option value="FindAllString" selected>FindAllString</option> 
       <option value="FindString">FindString</option> 
       <option value="FindStringSubmatch">FindStringSubmatch</option> 
    </select> 

はまた、あなたは、単にこのようなループを書くことができていることに注意をテンプレートの実行のためのライターとしてos.Stdoutを渡すだけで、バッファを作成して使用することなくコンソールに結果が表示されます。例えば、

err = t.Execute(os.Stdout, struct { 
    Types map[string]string 
    Res *Result 
}{types, res}) 

Go Playgroundで簡易版をお試しください。

さらに詳しい情報を得るためにこの回答を読んでください。golang template engine pipelines

関連する問題