设置集合上的属性 - 主干js

idb*_*ley 56 javascript collections backbone.js

主干js中的集合不允许您使用set属性,但我经常发现需要存储有关集合的一些元信息.设置该信息的最佳位置在哪里?

Ray*_*nos 44

只是.extend具有元数据存储功能的集合.

var MyCollection = Backbone.Collection.extend({
    initialize: function() {
        ...

        this._meta = {};
    },
    model: ...
    meta: function(prop, value) {
        if (value === undefined) {
            return this._meta[prop]
        } else {
            this._meta[prop] = value;
        }
    },
});

var collection = new MyCollection();
collection.add(someModels);
collection.meta("someProperty", value);

...

var value = collection.meta("someProperty");
Run Code Online (Sandbox Code Playgroud)

存储特定元数据的位置可能更好,但这完全取决于元数据的内容.

用于存储通用元数据,扩展您的集合构造函数,并使用一个方法来处理它应该工作.

要小心,如果需要从服务器存储和加载这个元数据,那么你手头有一个更大的任务.

  • 事实证明,这并不是最好的方法.而是将集合包装在模型中.事实上,如果我在阅读文档的时候我会仔细阅读,因为他们在这里给出了一个例子:http://documentcloud.github.com/backbone/#FAQ-nested.元信息存在于包装模型中.这应该有所帮助. (20认同)

Wyt*_*tze 17

最好按照预期的方式使用Collection:作为一组模型.(朱利安已经在OP上发表了这个评论,我想解释为什么我认为他是对的)

假设您正在考虑Book(模型)的库(集合),如Backbone的文档示例中所示.您有关于要存储的库的元信息(例如,此书库所在的地址)是有道理的.

诀窍不是将其视为元信息.你有一个拥有很多属性的库,其中一个属性是它的书籍集合.

var Book = Backbone.Model.extend({ 
    title: "Moby Dick"
});

var Collection = Backbone.Collection.extend({
    model: Book
});

var Library = {
    address: '45th Street',
    collection: Collection
};
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我将Library定义为一个普通的JavaScript对象.显然你也可以让Library成为一个模型,这样它就拥有了所有的Backbone铃声和口哨声.我的观点是,你需要以一种更现实的方式表现现实,退一步看看你想要分配给Collection的额外属性实际上是一级对象的兄弟属性:在这种情况下的库.



Ant*_*pin 7

我已经通过事件触发升级了Raynos的方法,因此我们可以绑定到集合的属性更新.

cls.groups = Backbone.Collection.extend({

    // ...

    // Reference to this collection's model.
    model: cls.group,

    initialize: function() {
        this._attributes = {}
    },

    // Extend collection with ability to store attributes and trigger events on attributes changing
    attr: function(prop, value) {
        if (value === undefined) {
            return this._attributes[prop]
        } else {
            this._attributes[prop] = value;
            this.trigger('change:' + prop, value);
        }
    },

    // ...

});


cls.group = Backbone.View.extend({

    // ...

    initialize: function() {

        // Catching attribute update
        app.groups.on('change:selected', function(value) {
            // ...
        }, this);
    },

    // ...

    events: {
        'click' : function(e) {
            // Set collection meta attribute on model's view click event
            app.groups.attr('selected', this.model.cid);
        }
    }

    // ...

});
Run Code Online (Sandbox Code Playgroud)