ember.js如何为视图显示不同的筛选列表?复杂的设置

时间:2012-03-01 18:11:49

标签: javascript ember.js

我有一个应用程序,我有一个汽车视图,我有一个国家/地区的列表,每个国家/地区都有一个复选框,当我检查一个国家/地区时,它会显示下面的视图,其中包含该国家/地区的可用部件列表。

检查更多国家/地区会在页面下方的更多国家/地区显示这些部分。

这些部件都存储在一个地方,但需要通过国家/地区进行过滤,以便只显示该国家/地区的部分内容。

我可以创建国家/地区列表,在选中时会显示下面的国家/地区部分,其中包含部件列表,但如何过滤以仅显示该国家/地区。我是否需要为每个国家和控制器创建视图以显示每个国家/地区的部分?

当然有更好的方法。

编辑:

这就是我需要显示页面的方式:

Coutries : UK <- selected

           USA

           China <- selected


Parts available in UK:

....

Parts available in China

....

所以我需要显示每个选定国家/地区的单独列表。

请帮忙 瑞克

3 个答案:

答案 0 :(得分:11)

使用嵌套视图可能最好解决这个问题。你可以看到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('partsList.@each').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})
    ]);
});
​

答案 1 :(得分:2)

我会像这样构建你的应用程序:

  1. 只有列表o部件对象的模型。每个对象都包含每个国家/地区中存在的部分数量。
  2. 根据所选国家/地区过滤该列表的控制器。
  3. 在控制器中设置选择国家/地区的视图。
  4. 一个视图,显示控制器中包含所选部件的列表。
  5. 我在这做过:

    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>
    

答案 2 :(得分:1)

对于部件列表,您可以使用绑定到控制器上的集合的#each帮助程序。控制器可以观察绑定到当前所选国家的控制器。当选择更改时,它将更新集合,这将自动更新您的零件清单。