【问题标题】:Ember group bindingEmber 组绑定
【发布时间】:2015-01-22 16:51:23
【问题描述】:

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

| 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 方式是什么,以便很好地绑定,如果我改变国家或联赛 - 球员会被渲染到适当的单元格中?

【问题讨论】:

    标签: javascript ember.js ember-data


    【解决方案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

    【讨论】:

    • 非常感谢!我已经被绑定助手卡住了一段时间,但没有研究组件:)
    【解决方案2】:

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

    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... 确保当国家/league 为玩家更新 - 信息被重新渲染。)

    你的模板可能看起来像这样:

    <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

    【讨论】:

    • 是的,这是一个更好的方法。快速提问:有没有办法让它成为块?这样就可以做到:{{#filterByCountryAndLeague... }} {{render 'player.card' player}} {{/filterByCountryAndLeague}}
    猜你喜欢
    • 2016-04-10
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    相关资源
    最近更新 更多