4

を使用してtext/template、配列内のオブジェクトに特定のプロパティ値があるかどうかを確認する必要があります。

人のリスト(json)があるとしましょう:

[
    {"name": "ANisus", "sex":"M"},
    {"name": "Sofia", "sex":"F"},
    {"name": "Anna", "sex":"F"}
]

テンプレートを使用して、次の出力が必要です。

Females:
Sofia
Anna

ただし、ヘッダー は、実際に が設定されているFemales:人がいる場合にのみ表示されます。テンプレート システム内でこれを実行するにはどうすればよいですか? 私の最初の試みは、変数を使用することでした:sexF

{{$hasFemale := 0}}
{{range .}}{{if eq .sex "F"}}{{$hasFemale := 1}}{{end}}{{end}}
{{if $hasFemale}}Female:{{end}}

範囲内の $hasFemale が別のスコープにあり、0 で開始されたものと同じではないため、これを機能させることができませんでした。開始された変数を変更する方法が見つからないようです。

「動作中」の例: http://play.golang.org/p/T-Ekx7n9YQ

そして、このロジックをアプリケーションに移すことはできません。テンプレート内で行う必要があります。

4

2 に答える 2

4

私はこれを別の方法で解決します。通常、テンプレートに状態は必要ありません。テンプレートは単純であるべきです。

データセットに女性がいるかどうかだけを知りたいので、データにメソッドHasFemalesを定義し、テンプレートから呼び出します。必ずしも構造体を定義する必要はありません。カスタム型と次のような定義を使用できます (変更された例 on play ):

type People []interface{}

func (p People) HasFemale() bool {
    for _, v := range p {
        if m, ok := v.(map[string]interface{}); !ok {
            return false
        } else if _, ok := m["sex"]; ok && m["sex"] == "F" {
            return true
        }
    }
    return false
}

テンプレートは次のようになります。

{{if .HasFemale}}Female:
    {{range .}}{{if eq .sex "F"}}{{.name}}{{end}}{{end}}
{{end}}

もちろん、これは構造体ほどタイプ セーフではなく、構造体ほど優れているわけでもないため、encoding/jsonリフレクション機能を使用して値を構造体にマップし、その上でメソッドを定義することをお勧めします。これには、結果を内部的にキャッシュできるという利点もあるため、.HasFemale毎回反復する必要はありません。

あなたのコメントに関する更新

1) テンプレート ファイルと 2) json ファイルの 2 つの引数を取る Go アプリケーションがあります。データを使用してテンプレートを実行し、ファイルを出力します。次に、出力ファイルが wkhtmltopdf に渡され、pdf が生成されます。各テンプレート/データのペアは、私の制御を超えた任意のデータ構造を持っているため、Go アプリケーションは汎用的でなければなりません

この場合はHasFemaleジェネリックにします。これは質問で行ったことと似ていますが、範囲のネストを抽象化する利点があり、結果を変数に格納してテンプレート全体に状態を保持できます。例:

type Data []interface{}

func (p Data) HasField(name string, value interface{}) bool {
    for _, v := range p {
        if m, ok := v.(map[string]interface{}); !ok {
            return false
        } else if _, ok := m[name]; ok && reflect.DeepEqual(m[name], value) {
            return true
        }
    }
    return false
}

使用例:

{{$hasFemale := .HasField "sex" "F"}}
{{if $hasFemale}}Female:
    {{range .}}{{if eq .sex "F"}}{{.name}}{{end}}{{end}}
{{end}}`
于 2013-10-10T11:01:49.320 に答える
1

これは古い質問であることは知っていますが、フィールドが範囲内に存在するかどうかに応じて、html テーブルの列をオプションにする必要がある同様のユースケースがありました。

元のポスターはほとんどそこにありました.goで頻繁に問題が発生し、変数を間違ったスコープに設定していました.

{{$hasFemale := 1}}そのため、if 内で変数を設定する代わりに{{$hasFemale = 1}}、最初に記述したとおりに機能するように記述する必要がありました。

{{$hasFemale := 0}}
{{range .}}{{if eq .sex "F"}}{{$hasFemale = 1}}{{end}}{{end}}
{{if $hasFemale}}Female:{{end}}

https://play.golang.org/p/m_RPJmqsuetを修正した元の例を次に示します。

于 2021-09-08T06:32:41.197 に答える