Как фильтровать коллекцию контента ArrayController в Ember.js с помощью флажка в представлении?

Я использую последний код как для Ember, так и для Ember-Data. У меня есть рельсы в качестве моего бэкэнда, поставляющего JSON, который работает нормально. Я хочу иметь возможность фильтровать «активное» свойство модели Ember, используя флажок в моем представлении. Я хочу, чтобы флажок отображал только те данные, которые активны = true, если я устанавливаю флажок. Я НЕ хочу удалять данные из массива, только СКРЫВАТЬ данные. Это то, что у меня сейчас есть, но оно не работает.

Модель:

App.Org = DS.Model.extend({
    code: DS.attr('string', { defaultValue: 'N/A' }),
    name: DS.attr('string', { defaultValue: 'N/A' }),
    source: DS.attr('string', { defaultValue: 'N/A' }),
    status: DS.attr('string', { defaultValue: 'N/A' }),
    type: DS.attr('string', { defaultValue: 'N/A' }),
    note: DS.attr('string', { defaultValue: 'N/A' }),
    financial_Flag: DS.attr('string', { defaultValue: 'N/A' }),
    expense_Flag: DS.attr('string', { defaultValue: 'N/A' }),
    revenue_Flag: DS.attr('string', { defaultValue: 'N/A' }),
    created_At: DS.attr('string', { defaultValue: 'N/A' }),
    updated_At: DS.attr('string', { defaultValue: 'N/A' }),

    active: function() {
        var status = this.get('status');
        var active = (status === 0) ? false : true;
        console.log("status: " + status + " | active: " + active);
        return active;
    }.property('status')

}).reopenClass({
    collectionUrl: '/orgs',
    resourceUrl: '/orgs/%@',
    resourceName: 'org'
});

Контроллер массива:

App.OrgsController = Em.ArrayController.extend({

    isEmpty: function() {
        console.log("############ App.OrgsController.isEmpty called");
        return this.get('length') === 0;
    }.property('length'),

    toggleActive: function(){
        console.log("############ App.OrgsController.isActive called");
        return this.filterProperty('active', value).forEach(this.removeObject, this);
    }.property('@each.active'),

    init: function() {
        this.set('content', App.store.findAll(App.Org));
    },

    refreshOrgs: function() {
        this.set('content', App.store.findAll(App.Org));
    },

    getInactiveOrgs: function(){
        this.set('content', App.store.find(App.Org, {status: "0"}));
    }
});

На мой взгляд, у меня есть:

<label>
    isActive
    {{view Ember.Checkbox checkedBinding="App.OrgsController.toggleActive" disabledBinding="App.OrgsController.isEmpty" }}
</label>

person Jason Cochran    schedule 20.09.2012    source источник
comment
Не уверен, что это поможет, но поскольку вы используете ember-data, возможно, вы захотите использовать App.store.filter вместо свойства filterProperty контроллера?   -  person dechov    schedule 21.09.2012
comment
Хм... попробую. Спасибо!   -  person Jason Cochran    schedule 21.09.2012


Ответы (1)


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

App.Post = DS.Model.extend({
    text: DS.attr('string'),
    active: DS.attr('boolean')
});

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return App.Post.find();
    }
});

App.IndexController = Ember.ArrayController.extend({
    hideInactive: false,

    filteredContent: function() {
        var content = this.get('content');

        if (!content || !this.get('hideInactive'))
            return content;

        return content.filter(function(item) {
            return item.get('active');
        });
    }.property('content.isLoaded', 'hideInactive')
});

Ваш шаблон должен выглядеть примерно так:

<script type="text/x-handlebars" data-template-name="index">
    <p>{{view Ember.Checkbox checkedBinding="hideInactive"}} Hide Inactive Posts</p>
    <br/>

    {{#each filteredContent}}
        <p>{{text}}</p>
    {{/each}}
</script>

Это также будет работать, если active определено как вычисляемое свойство, как в вашем примере.

person ahmacleod    schedule 19.02.2013