在Handlebars中如何迭代一个对象?

28

这是我的数据的一般要点(从 Chrome WebKit Inspector 复制了外观)。

> 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,那也可以,但最好是只用这个设置。

5个回答

21

只需使用 "this"。

`<script id="some-template" type="text/x-handlebars-template">
<option value="none">Selec</option>
{{#each data}}
    <optgroup label="{{@key}}">
    {{#each this}}
        <option value="{{id}}">{{name}}</option>
    {{/each}}
    </optgroup>
{{/each}}
</script>`

http://jsfiddle.net/rcondori/jfav4o6u/


不错。我不知道你可以这样做 {{#each this}} - Robert Dundon

12

您当前的数据格式存在两个问题:

  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>
你可以编写一个辅助函数来迭代一个对象,但是如果你想确保显示的顺序合理,仍需要在数组中指定键。

好的回答。我在构建应用程序时仍然很新手,真正利用JavaScript,我无法理解如何使用数组组织数据...我从来没有想过只需放置'name:<foo>',然后根据此进行迭代。 - Rey
我也喜欢你创建一个对象并将其他对象分配给它的方式...我一直在想...如果我要循环遍历没有名称的数组...那么你只需将其放入对象中,这样你就可以给它一个名字...聪明。 - Rey

1
你可以通过自定义组件来实现这一点,参见示例,这不受我们默认的{{each}}助手的支持(这是有意的)。 示例数据:
a = {a:'muhammad', b :'asif', c: 'javed', username: 'maxifjaved'}

**

遍历对象的在线演示

http://emberjs.jsbin.com/yuheke/1/edit?html,js,output

**


0
就Handlebars-only解决方案而言,我已经实现了这个逻辑。
{{#each Listings}} 

<a href="javascript:void(0)" title="" ><img src="    {{DefaultImage}}" alt=" {{Make}} {{Model}}" /> </a>

0

我更喜欢胡子先生 :-{)

但从这里的文档来看,似乎这种方法可以解决问题:

<select>
  <option value="">All Shows (default)</option>
  <optgroup label="Fruit">
    {{#each Fruit}}
    <option value="{{id}}">{{name}}</option>
    {{/each}}
  </optgroup>
  <!-- repeat for others-->
</select>

你不仅在代码中硬编码了水果(Fruit)的optgroup,而且还手动指定了循环变量名为Fruit。我想为每种食品类型创建一个optgroup,然后在这些optgroup里添加它们各自对应的选项。 - Rey
只需按照mu所提到的方式嵌套循环即可。 - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接