2012-03-01 51 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

相关问题