1. ホーム
  2. javascript

[解決済み] Handlebars 用のオブジェクトを繰り返し処理する?重複

2022-02-11 16:40:42

質問

これが私のデータの大まかな流れです(クロームのwebkitインスペクタから見た感じをコピーしたものです)。

> Object
  > Fruit: Array[2]
    > 0: Object
       name: "banana"
       color: "yellow"
       animalthateats: "monkey"
       id: 39480
    > 1: Object
    length: 2
  > Vegetables: Array[179]
  > Dairy: Array[2]
  > Meat: Array[3]
  > __proto__: Object

そして、これが私のやりたいことです(一般的に)。

<select>
  <option value="">All Shows (default)</option>
  <optgroup label="Fruit">
    <option value="39480">Banana</option>
    <option value="43432">Strawberry</option>
  </optgroup>
  <optgroup label="Vegetables">
    <option value="3432">Broccoli</option>
  </optgroup>
</select>

私は全体のテンプレート化することにある種の新しい、そしてそれは確かに達成するために非正規のようです...私はとにかくjQueryを使用することができれば、それはあまりにも動作しますが、できればこのセットアップでだけです。

どのように解決するのですか?

現在のデータフォーマットでは、2つの問題があります。

  1. Handlebars は、オブジェクトではなく、配列を繰り返し処理することを望んでいます。
  2. JavaScript のオブジェクトには信頼できる順序がありません。

このように、データをネストした配列に並べ替えることができれば、より良い結果が得られるでしょう。

var foods  = { /* what you already have */ };
var for_hb = [
        { name: 'Fruit',      foods: foods.Fruit },
        { name: 'Vegetables', foods: foods.Vegetables },
        //...
];

こんな簡単なものでいいんです。

var for_hb = [ ];
for(var k in foods)
    for_hb.push({name: k, foods: foods[k]});
for_hb.sort(function(a, b) {
    a = a.name.toLowerCase();
    b = b.name.toLowerCase();
    return a < b ? -1
         : a > b ? +1
         :          0;
});

var html = compiled_template({ groups: for_hb });

そうすると、テンプレートはシンプルになります。

<select>
  <option value="">All Shows (default)</option>
  {{#each group}}
    <optgroup label="{{name}}">
    {{#each foods}}
      <option value="{{id}}">{{name}}</option>
    {{/each}}
  {{/each}}
</select>

オブジェクトを繰り返し処理するヘルパーを書くこともできますが、適切な表示順序を確保するためには、キーを配列で指定する必要があります。