我正在使用几个主干集合,有时我需要根据某些标准访问它们的一部分。
方法1
正如this question中所述,在集合本身使用filter()
会返回一个模型数组,而不是另一个集合。这可以在简单的情况下工作,但它会失去集合的方法连接,因为普通的模型数组不会在集合中定义所有方法。
方法2
该问题的答案建议创建一个新的集合,将模型数组传递给构造函数。这有效,但每次调用集合的构造函数都有副作用,因此每次过滤集合时,任何可能在那里定义的事件绑定都会堆叠。
那么基于某些过滤条件创建子集合的正确方法是什么?
我应该使用方法1并依靠方法链来创建更多的过滤方法吗?
我应该使用方法2并避免在集合的构造函数中绑定事件吗?
答案 0 :(得分:1)
我个人会在集合上创建更多的过滤方法,因为它具有在集合中封装逻辑的额外好处。
您还可以尝试重用现有的集合。我正在考虑这个想法,并得出这样的东西:
var Collection = Backbone.Collection.extend({
//Takes in n arrays. The first item of each array is the method you want
//to call and the rest are the arguments to that method.
//Sets the collection.models property to the value of each successive filter
//and returns the result of the last. Revers the collection.models to its original value.
chainFilters: function(/*args..*/) {
var models = this.models;
try {
filters = _.toArray(arguments);
_.each(filters, function(filter) {
this.models = filter[0].apply(this, _.rest(filter));
}, this);
} catch(err) {
this.models = models;
throw err;
}
var filtered = this.models;
this.models = models;
return filtered;
}
});
用法:
var results = collection.chainFilters(
[ collection.filter, function(model) { return model.get('name') === 'foo'; } ],
[ collection.someMethod, 'someargument' ],
[ collection.someOtherMethod ]
);
Here's a working sample.我知道这有点奇怪。
答案 1 :(得分:0)
这取决于用例。如果您希望这些模型更新视图,那么您可能需要一个新的集合,否则您将无法获得良好的反应模板更新。如果您只是希望模型迭代或操作数据而不用担心数据更新,那么使用数组+ underscore.js。
尝试使用数组,如果你发现自己编写了大量的锅炉板代码,其中的功能已经在一个集合中而不是在underscore.js中,那么就开始使用一个集合。