ハンドルバー/口ひげ-オブジェクトのプロパティをループする組み込みの方法はありますか?


216

質問のタイトルが言うように、オブジェクトのプロパティをループする口ひげ/ハンドルバーの方法はありますか?

だから

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
}

私は、何かを行うことができますテンプレートエンジンに同等になります

for(var prop in o)
{
    // with say, prop a variable in the template and value the property value
}

回答:


448

ハンドルバー1.0rc1以降の組み込みサポート

この機能のサポートがHandlebars.jsに追加されたため、外部ヘルパーは必要ありません。

どうやって使うのですか

アレイの場合:

{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}

オブジェクトの場合:

{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}

hasOwnPropertyテストに合格するプロパティのみが列挙されることに注意してください。


2
@Rafi:データ構造を知らなければ、それを理解することはできません。
Jon

3
@Rafi:{{this.title}}を意味するのではないですか?
2013年

2
@qodeninja:シンプル:上記の例の値を参照するのと同じ方法で-を使用し{{#each this}}ます。用語の選択もわかりにくいので(あるオブジェクトを「トップレベル」にし、別のオブジェクトをそうしないのか?「定義済み」のキーとは正確に何なのかなど)、これらの概念を再検討する必要があるかもしれません。
Jon

1
間違っていない場合は、v1.1.0でのみ使用できますが、回答ありがとうございます。
Renars Sirotins

2
プロパティの特定のホワイトリストに対してのみこれをどのように行いますか?
Marco Prins、2015

70

実際、ヘルパーとして実装するのは非常に簡単です。

Handlebars.registerHelper('eachProperty', function(context, options) {
    var ret = "";
    for(var prop in context)
    {
        ret = ret + options.fn({property:prop,value:context[prop]});
    }
    return ret;
});

次に、それを次のように使用します。

{{#eachProperty object}}
    {{property}}: {{value}}<br/>
{{/eachProperty }}

2
よさそうです、プロトタイププロパティを繰り返し処理しないように、ループ内にhasOwnPropertyチェックを追加する必要がありますか?
モンキーボーイ、

ベンの素晴らしいソリューション。Emberでこれを使用しようとしている場合は、それを機能させるための解決策について、以下の私の回答を参照してください。
Flynfish 2013年

27

編集:ハンドルバーには、これを実現する組み込みの方法があります。上記の選択した回答を参照してください。プレーンな口ひげを使用する場合、以下が引き続き適用されます。

Mustacheは、配列内の項目を反復処理できます。したがって、Mustacheが動作できるようにフォーマットされた個別のデータオブジェクトを作成することをお勧めします。

var o = {
  bob : 'For sure',
  roger: 'Unknown',
  donkey: 'What an ass'
},
mustacheFormattedData = { 'people' : [] };

for (var prop in o){
  if (o.hasOwnProperty(prop)){
    mustacheFormattedData['people'].push({
      'key' : prop,
      'value' : o[prop]
     });
  }
}

これで、Mustacheテンプレートは次のようになります。

{{#people}}
  {{key}} : {{value}}
{{/people}}

こちらの「空でないリスト」セクションをご覧くださいhttps : //github.com/janl/mustache.js


1
とにかく、いくつかの追加のサブプロパティを渡す必要があるため、最終的にはあなたの提案に行き着きました。助けてくれてありがとう!
Ben

どうもありがとうございました。あなたのアイデアにより、別の方法を探す必要がなくなりました。この行がキーであるmustacheFormattedData = {'people':[]};
Matt

「o」オブジェクトの配列でこれをどのように行いますか?
red888 2014

4

これは、Emberで使用するために更新された@Benの回答です。Ember.getコンテキストは文字列として渡されるため、使用する必要があります。

Ember.Handlebars.registerHelper('eachProperty', function(context, options) {
  var ret = "";
  var newContext = Ember.get(this, context);
  for(var prop in newContext)
  {
    if (newContext.hasOwnProperty(prop)) {
      ret = ret + options.fn({property:prop,value:newContext[prop]});
    }
  }
  return ret;
});

テンプレート:

{{#eachProperty object}}
  {{key}}: {{value}}<br/>
{{/eachProperty }}

@flynfishに感謝します。コンテキストはEmberの文字列ですか?どうやら..少し変だ。
ベン

ええ、私はEmberを初めて使い、それでも自分の道を見つけようとしているので、よくわかりません。
Flynfish 2013年

1

@Amitの答えは、MustacheとHandlebarsの両方で機能するので良いです。

ハンドルバーのみのソリューションに関しては、いくつか見たことがありますがhttps://gist.github.com/1371586each_with_keyブロックヘルパーが最高です。

  • 最初に再構築せずにオブジェクトリテラルを反復処理できます。
  • これにより、キー変数と呼ばれるものを制御できます。他の多くのソリューションでは'key'、や'property'、などの名前のオブジェクトキーの使用に注意する必要があります。

いい発見。他の読者への単なる警告:この要点の「key_value」ヘルパーにはバグがあります。修正方法についてはコメントを読んでください。
2012年

0

ベンの解決策をありがとう、特定のフィールドのみを順番に表示するユースケース

オブジェクト付き

コード:

    handlebars.registerHelper('eachToDisplayProperty', function(context, toDisplays, options) {
    var ret = "";
    var toDisplayKeyList = toDisplays.split(",");
    for(var i = 0; i < toDisplayKeyList.length; i++) {
        toDisplayKey = toDisplayKeyList[i];
        if(context[toDisplayKey]) {
            ret = ret + options.fn({
                property : toDisplayKey,
                value : context[toDisplayKey]
            });
        }

    }
    return ret;
});

ソースオブジェクト:

   { locationDesc:"abc", name:"ghi", description:"def", four:"you wont see this"}

テンプレート:

{{#eachToDisplayProperty this "locationDesc,description,name"}}
    <div>
        {{property}} --- {{value}}
    </div>
    {{/eachToDisplayProperty}}

出力:

locationDesc --- abc
description --- def
name --- ghi

0

これは、データを事前にフォーマットせずに、レンダリング中に取得することなく、mustacheJSのヘルパー関数です。

var data = {
    valueFromMap: function() {
        return function(text, render) {
            // "this" will be an object with map key property
            // text will be color that we have between the mustache-tags
            // in the template
            // render is the function that mustache gives us

            // still need to loop since we have no idea what the key is
            // but there will only be one
            for ( var key in this) {
                if (this.hasOwnProperty(key)) {
                    return render(this[key][text]);
                }
            }
        };
    },

    list: {
        blueHorse: {
            color: 'blue'
        },

        redHorse: {
            color: 'red'
        }
    }
};

テンプレート:

{{#list}}
    {{#.}}<span>color: {{#valueFromMap}}color{{/valueFromMap}}</span> <br/>{{/.}}
{{/list}}

出力:

color: blue
color: red

(順序はランダムかもしれません-それはマップです)これはあなたが望むマップ要素を知っているなら便利かもしれません。偽の値に注意してください。


-1

私は古いバージョン1.0.beta.6のハンドルバーを使用していましたが、1.1〜1.3のどこかにこの機能が追加されたと思います。したがって、1.3.0に更新すると問題が解決しました。使用方法は次のとおりです。

使用法:

{{#each object}}
  Key {{@key}} : Value {{this}}
{{/people}}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.