2

我有一个代表产品的模型(在 UL 中显示为 LI 项)和一个包含这些产品的集合。

当我单击一个 LI 时,我希望底层模型的属性设置为 true,并且集合中的所有其他模型的属性设置为 false。

//Model for product
        var cs_product = Backbone.Model.extend({
            defaults: function(){

                return {
                    name: '',
                    active: false
                };

            },
            initialize: function(){

                if(!this.get('name'))
                    this.set({'name': this.defaults.name});

            },
            toggle: function(){


                this.set({
                    active: !this.get('active')
                });

            }
        });





        //Collection of all products this user has access to
        var cs_products = Backbone.Collection.extend({
            _products: [],
            initialize: function(cs_products){
                this._products = cs_products
            },          
            model: cs_product //<-- creates an instance of the cs_product model for each of our products
        });     
        var user_client_products = new cs_products(globals.cs_user.cs_suite_products);
        user_client_products.on('change:active', function(el, i, list){

            console.log('collection change event');
            console.log(arguments);
            console.log(el.toJSON());

            //loop over all models in collection and set active to false except for this?
            this.each(function(el2){

                if(el === el2)
                    return;

                console.log(el2);

                el.set({active: false});


            });


        });
4

1 回答 1

3

集合中模型上的事件也会在集合上触发

Backbone.Collection
[...]
为方便起见,在集合中的模型上触发的任何事件也将直接在集合上触发。这使您可以侦听集合中任何模型中特定属性的更改,例如:Documents.on("change:selected", ...)

因此,您的集合"change:active"只需绑定到其自身的事件即可从其模型中侦听事件"change:active"。然后它可以将其余模型本身设置为不活动:

var cs_products = Backbone.Collection.extend({
    model: cs_product,
    initialize: function() {
        _.bindAll(this, 'propagate_active');
        this.on('change:active', this.propagate_active);
    },
    propagate_active: function(p) {
        if(!p.get('active'))
            return;
        this.each(function(m) {
            if(p.id != m.id)
                m.set({ active: false }, { silent: true });
        });
    }
});

演示:http: //jsfiddle.net/ambiguous/WEkmy/


顺便说一句,没有理由自己跟踪集合中的模型:

var cs_products = Backbone.Collection.extend({
    _products: [],
    initialize: function(cs_products) {
        this._products = cs_products; // <------------- ????
    },
    //...
});

集合是带有一些装饰的模型列表,因此所有内容都已烘焙。您可以通过this.models集合内部访问模型数组,也可以使用烘焙的 Underscore 方法迭代集合的模型。

于 2012-06-10T00:11:12.897 回答