Ember group binding

走远了吗. 提交于 2019-12-24 16:58:23

问题


I'm looking for a good way to bind grouped objects and render it to the grid. Here's a grid example:

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

And Player's model

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

And data received from backend is:

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

I thought about having something following:

{{#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}}

But having filtering within template does not look good. Is there a good way to move it to controller?

What is the Ember-way to output list of players into such grid, so that it nicely bound and if I change country or league - player is rendered into proper cell?


回答1:


Following up on your question in the comment:

is there any way to have it [bound helper] as block? So that it's possible to do: {{#filterByCountryAndLeague... }} {{render 'player.card' player}}

The answer is yes and no. So, as a bound helper? No. See the docs here

Bound helpers do not support use with Handlebars blocks or the addition of child views of any kind.

But... if you need to use a template to display each player's info, you can use a component instead of a bound helper.

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')
});

Then, inside your component template, you can render a specialized template per each player:

<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>

Working demo here




回答2:


You can write a bound helper for this as follows:

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');

Inside the helper function, you are passing all players as well as current country and league being processed and are filtering the allPlayers array by the values passed in. (The @each... at the end makes sure that when the country/league update for the player - the info gets rerendered.)

Your template then can look something like this:

<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>

Working demo here



来源:https://stackoverflow.com/questions/28094306/ember-group-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!