2012-03-01 52 views
4

我有一個應用程序,我有一個汽車視圖,我有一個複選框對每個國家的列表,當我檢查一個國家時,它顯示下面的視圖與該國家可用部件列表。ember.js如何顯示視圖的不同過濾列表?複雜的設置

檢查更多的國家顯示在下一頁更多國家的部分。

零件都存儲在一個位置,但需要通過coutry字段進行過濾以僅顯示該國家/地區的零件。

我可以創建國家列表,當選中它時會顯示下面的國家部分以及其中的部分列表,但我如何過濾才能顯示該國家/地區。我是否需要爲每個國家和每個國家/地區的控制器創建視圖以顯示?

當然有更好的方法。

編輯:

這就是我需要的頁面顯示:

Coutries : UK <- selected 

      USA 

      China <- selected 


Parts available in UK: 

.... 

Parts available in China 

.... 

所以我需要OFR選擇每個國家單獨的顯示列表。

請幫 裏克

回答

10

這很可能是最好使用嵌套視圖解決。你可以看到my jsFiddle here

我不認爲這是一個非常複雜的方法,但如果您有任何關於設計的問題,請讓我知道。

把手:

<script type="text/x-handlebars"> 
    {{#each App.countriesController}} 
     {{view Ember.Checkbox titleBinding="name" valueBinding="isChecked"}} 
    {{/each}} 
    <hr /> 
    {{#each App.countriesController}} 
    {{#if isChecked}} 
     {{view App.PartsByCountryView contentBinding="this" partsListBinding="App.partsController"}} <br />  
    {{/if}} 
{{/each}} 
</script> 

<script type="text/x-handlebars" data-template-name="selected-country"> 
    Country: {{content.name}} <br /> 
    Parts: 
    {{#each filteredParts}} 
     {{name}} 
    {{/each}} 
</script> 
​ 

應用代碼:

window.App = App = Ember.Application.create(); 
/************************** 
* Models 
**************************/ 
App.Country = Ember.Object.extend({ 
    id: null, 
    name: "", 
    isChecked: null 
}); 

App.Part = Ember.Object.extend({ 
    id: null, 
    name: "", 
    countryId: null 
}); 

/************************** 
* Views 
**************************/ 
App.PartsByCountryView = Ember.View.extend({ 
    content: null, 
    partsList: null, 
    templateName: 'selected-country', 

    filteredParts: function() { 
     return this.get("partsList").filterProperty('countryId', this.getPath('content.id')) 
    }.property('[email protected]').cacheable() 
}); 

/************************** 
* Controllers 
**************************/ 
App.set('countriesController', Ember.ArrayController.create({ 
    content: Ember.A() 
})); 

App.set('partsController', Ember.ArrayController.create({ 
    content: Ember.A() 
})); 

/************************** 
* App Logic 
**************************/ 
$(function() { 
    App.get('countriesController').pushObjects([ 
     App.Country.create({id: 1, name: "USA"}), 
     App.Country.create({id: 2, name: "UK"}), 
     App.Country.create({id: 3, name: "FR"}) 
    ]); 

    App.get('partsController').pushObjects([ 
     App.Part.create({id: 1, name: "part1", countryId: 1}), 
     App.Part.create({id: 2, name: "part2", countryId: 1}), 
     App.Part.create({id: 3, name: "part3", countryId: 1}), 
     App.Part.create({id: 4, name: "part4", countryId: 2}), 
     App.Part.create({id: 5, name: "part5", countryId: 2}), 
     App.Part.create({id: 6, name: "part6", countryId: 2}), 
     App.Part.create({id: 7, name: "part7", countryId: 2}), 
     App.Part.create({id: 8, name: "part8", countryId: 3}), 
     App.Part.create({id: 9, name: "part9", countryId: 3}), 
     App.Part.create({id: 10, name: "part10", countryId: 3}), 
     App.Part.create({id: 11, name: "part11", countryId: 3}) 
    ]); 
}); 
​ 
+0

嗨羅伊謝謝你的偉大答案。只有一個問題:如果我轉到控制檯並嘗試添加另一部分像這樣'App.get('partsController')。pushObjects(App.Part.create({id:999,name:「part999」,countryId: 2})]); '我如何將它添加到相關部分而不必點擊複選框並再次打開?再次感謝 – 2012-03-06 13:50:04

+0

對不起,我忘了添加一個屬性來觀察我的filteredParts計算屬性的定義。我更新了代碼和jsFiddle。這個成功地回答了你的問題嗎? – 2012-03-06 13:57:38

+0

哇,非常快,非常感謝你,是的,這已經完全解答了我的問題。 – 2012-03-06 14:02:53

1

對於零件清單,你可以使用一個#each幫手綁定到一個集合的控制器上。控制器可以觀察綁定到當前選定國家的控制器。當選擇發生變化時,它會更新集合,這會自動更新您的零件列表。

+0

感謝,但這樣會創建一個列表,其中包含在選定的國家提供的所有零部件。但我需要單獨展示這些。請參閱我上面的編輯。有任何想法嗎 ? – 2012-03-05 13:18:28

2

我將構建應用程序是這樣的:

  1. 模型只是一個列表O部件對象。每個對象擁有每個國家有多少部分存在。
  2. 根據所選國家/地區過濾該列表的控制器。
  3. 在控制器中設置哪些國家被選中的視圖。
  4. 一個顯示控制器與選定零件的列表的視圖。

我所做的,在這裏:

http://jsfiddle.net/NPeeQ/2/

window.App = Ember.Application.create(); 

App.model = Ember.Object.create({ 

    parts: Ember.ArrayProxy.create({ 
     content: [ 
     { 
      name: 'wheel', 
      stock: { 
       uk: 3, 
       fi: 2, 
       se: 0 
      } 
     }, 
     { 
      name: 'windscreen', 
      stock: { 
       uk: 0, 
       fi: 1, 
       se: 3 
      } 
     } 
    ]}), 

    countries: ['uk', 'fi', 'se'] 

}); 

App.partController = Ember.Object.create({ 

    filterBy: {}, 

    setFilterBy: function (country, on) { 

     var filterBy = $.extend({}, this.get('filterBy')); 

     if (on) { 
      filterBy[country] = true; 
     } else { 
      delete filterBy[country]; 
     } 

     this.set('filterBy', filterBy); 

    }, 

    // returns all available parts filtered by filterBy. 
    availableParts: function() { 

     var parts = App.model.parts; 

     var filter = this.filterBy; 

     var arr = []; 

     App.model.countries.forEach(function(c) { 

      if (!filter[c]) return; 

      arr.push({heading:c}); 

      var tmp = App.model.parts.filter(function(p) { 
       return p.stock[c] && p.stock[c] > 0; 
      }); 

      arr = arr.concat(tmp); 

     });    

     return arr; 

    }.property('filterBy', 'App.model.parts').cacheable() 

}); 

App.SelectorView = Ember.View.extend({ 
    templateName: 'selector', 

    click: function(event) { 

     if (event.target.tagName !== 'INPUT') 
      return; 

     var clicked = $(event.target).closest('label'); 
     var index = this.$().find('label').index(clicked); 

     var country = App.model.countries[index]; 
     var on = event.target.checked; 

     App.partController.setFilterBy(country, on); 

    } 
}); 

App.PartsView = Ember.View.extend({ 
    templateName: 'parts' 
}); 


$(function() { 

    App.selectorView = App.SelectorView.create(); 
    App.partsView = App.PartsView.create(); 

    App.selectorView.append(); 
    App.partsView.append(); 

}) 

而且車把:

<script type="text/x-handlebars" data-template-name="selector"> 
    {{#each App.model.countries}} 
    <label><input type="checkbox"/> {{this}}</label> 
    {{/each}} 
</script> 

<script type="text/x-handlebars" data-template-name="parts"> 

    {{#each App.partController.availableParts}} 

     {{#if heading}} 
     <h2>{{heading}}</h2> 
     {{else}} 
    {{name}} <br/> 
     {{/if}} 

    {{/each}} 

</script> 
+0

嗨馬丁非常感謝廣泛的答覆。這將解決我的問題,但我認爲這是Roy提供的更清潔的解決方案。我希望你同意。謝謝 – 2012-03-06 13:51:15

相關問題