Ember组绑定

时间:2015-01-22 16:51:23

标签: javascript ember.js ember-data

我正在寻找一种绑定分组对象并将其渲染到网格的好方法。这是一个网格示例:

| League / Country  | Canada     | United States     | Brazil   |
| 1                 | John, Sam  |                   | Tim      |
| 2                 | Liam       |                   | Robert   |
| 3                 |            | James, Peter, Tom | Den      |

和玩家的模特

DS.Model.extend({
    name: DS.attr(),
    country: DS.attr(),
    leagueId: DS.attr("number")
}); 

从后端收到的数据是:

[
  { name: "John", country: "Canada", leagueId: 1 },
  { name: "Sam", country: "Canada", leagueId: 1 },
  { name: "Tim", country: "Brazil", leagueId: 1 },
  { name: "Liam", country: "Canada", leagueId: 2 },
 ... 
]

我想到了以下内容:

{{#each country in countries}}
    <tr>
      {{#each league in leagues}}
        <td>
          {{#each player in players}}
            {{#is player.country "==" country}}
              {{#is player.leagueId "==" league}}
                ... output player ..., e.g. {{ render 'player/card' player }}
              {{/is}}
            {{/is}}
          {{/each}}
        </td>
      {{/each}}
    </tr>
{{/each}}

但是在模板中进行过滤看起来不太好。有没有一种好方法将它移动到控制器?

什么是Ember-way输出玩家列表到这样的网格,这样它很好地绑定,如果我改变国家或联盟 - 玩家被渲染到适当的单元格?

2 个答案:

答案 0 :(得分:1)

您可以为此编写绑定帮助程序,如下所示:

Ember.Handlebars.registerBoundHelper('filterByCountryAndLeague', 
  function(allPlayers, curCountry, curLeague) {
    var matched = allPlayers.filterBy("country", curCountry).
                             filterBy('leagueId', curLeague);

    return matched.mapBy('name').join(", ");
}, '@each.country', '@each.leagueId');

在帮助函数中,您传递所有玩家以及正在处理的当前国家/地区和联盟,并按照传入的值过滤allPlayers数组。(最后的@each...确保当玩家的国家/联盟更新时 - 信息会被重新渲染。)

您的模板可能如下所示:

<table border='2'>
  {{! First row }}
  <tr>
    <td>League / Country</td>
      {{#each country in countries}}
        <td>{{country}}</td>
      {{/each}}
  </tr>

  {{! Leagues }}
  {{#each league in leagues}}
    <tr>
      <td>{{league}}</td>
      {{#each country in countries }}
        <td>
          {{ filterByCountryAndLeague model country league  }}
        </td>
      {{/each}}
    </tr>
  {{/each}}

</table>

工作演示here

答案 1 :(得分:1)

在评论中跟进您的问题:

  

有没有办法让它[绑定帮助]作为块?所以可以这样做:{{#filterByCountryAndLeague ...}} {{render'player.card'player}}

答案是肯定的,不是。那么,作为一个约束帮助者呢?不。请参阅文档here

  

绑定助手不支持使用Handlebars块或添加任何类型的子视图。

但是...... 如果您需要使用模板来显示每个玩家的信息,您可以使用组件而不是绑定帮助器。

App.FilteredPlayersComponent = Ember.Component.extend({
  allPlayers: null, 
  forCountry: null, 
  forLeague: null,
  filteredPlayers: function(){
    var allPlayers = this.get('allPlayers');
    var forCountry = this.get('forCountry');
    var forLeague = this.get('forLeague');
    var matched = allPlayers.filterBy("country", forCountry).
                             filterBy('leagueId', forLeague);
    return matched;
 }.property('allPlayers.@each.country', 'forCountry', 'forLeague')
});

然后,在您的组件模板中,您可以为每个玩家render一个专门的模板:

<script type="text/x-handlebars" id="components/filtered-players">
  {{#each player in filteredPlayers}}
    {{ render "player.card" player }}
  {{/each}}
</script>  

<script type="text/x-handlebars" id="player/card">
  <b>{{player.name}}</b>
</script>

工作演示here