2015-01-22 4 views
1

Я ищу хороший способ привязать сгруппированные объекты и отобразить их в сетке. Вот пример сетки:Групповое связывание Ember

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

Но с фильтрацией g в шаблоне не выглядит хорошо. Есть ли хороший способ переместить его на контроллер?

Что такое Ember-way для вывода списка игроков в такую ​​сетку, так что это красиво связано, и если я изменю страну или лигу - игрок отображается в правильную ячейку?

ответ

1

Вслед за Ваш вопрос в комментарии:

есть ли способ, чтобы он [связан помощника] в качестве блока? Так что это можно сделать: {{#filterByCountryAndLeague ...}} {{render 'player.card' player}}

Ответ да и нет. Итак, как связанный помощник? Нет. Смотрите документы here

Связанные помощники не поддерживают использование с Рулями блоками или добавлением взглядов ребенка любого рода.

Но ... если вам нужно использовать шаблон для отображения информации каждого игрока, вы можете использовать компонент вместо связанного помощника.

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('[email protected]', '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

+0

Спасибо большое! Я некоторое время застрял с привязанным помощником, но не смотрел на компоненты :) – fantactuka

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 массива по значениям . прошел в (The @each... в конце гарантирует, что, когда обновление страны/лига для игрока - инфо получает rerendered.)

Ваш шаблон затем может выглядеть следующим образом:

<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

+0

Да, это лучший способ. Быстрый вопрос: есть ли способ иметь его как блок? Так что это можно сделать: '' '{{#filterByCountryAndLeague ...}} {{render 'player.card 'player}} {{/ filterByCountryAndLeague}} '' ' – fantactuka

Смежные вопросы