骨干过滤

时间:2012-05-24 16:41:54

标签: javascript collections backbone.js models underscore.js

如果我有一个Backbone集合并想要创建该集合的副本并过滤掉某些条目,那么如何在将复制的实例保持为Backbone.Collection的情况下执行此操作?

示例:

var Module = Backbone.Model.extend();

var ModuleCollection = Backbone.Collection.​extend({
    model: Module
});

​var modules = new ModuleCollection;

​modules.add({foo: 'foo'​​​​​​},{foo: 'bar'});​​​​​

console.log(modules instanceof Backbone.Collection); // true

var filtered = modules.filter(function(module) {
    return module.get('foo') == 'bar';
});

console.log(filtered instanceof Backbone.Collection); // false

http://jsfiddle.net/m9eTY/

在上面的示例中,我希望filtered是模块的过滤版本,而不仅仅是模型数组。

本质上我想在集合实例中创建一个可以过滤掉某些模型并返回Backbone.Collection实例的方法,但是一旦开始过滤,迭代方法就会返回一个数组。

2 个答案:

答案 0 :(得分:9)

如果需要,可以将过滤后的数组包装在临时的ModuleCollection中,过滤的模型与原始ModuleCollection中的模型相同,因此如果模块的属性发生更改,它仍会被两个集合引用。

所以我建议你这样做:

var filtered = new ModuleCollection(modules.filter(function (module) {
    return module.get('foo') == 'bar';
}));

从Backbone 0.9.2开始,还有一个名为where的方法也是如此:

var filtered = modules.where({foo: 'bar'});

仍会返回一个数组,所以你仍然需要将它包装起来:

var filtered = new ModuleCollection(modules.where({foo: 'bar'}));

答案 1 :(得分:0)

使用主干过滤收集

要制作过滤器,您应该在集合中使用过滤功能

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

我建议使用UnderScore过滤器,该过滤器将返回true表示有效,false表示无效,其中true表示您正在查找的内容。使用this.models获取当前集合模型使用model.get('')来获取要检查的元素

var results = _.filter( this.models, function ( model ) {           
    if ( model.get('foo') == 'bar' ) 
    return true ; 
    return false ;
});

然后使用下划线映射您的结果并将其转换为JSON,就像这样,这可能是您错误的地方

results = _.map( results, function( model ) { return model.toJSON()  } );

最后返回一个只有结果的新骨干集合,这就是如何制作复制的集合

return new Backbone.Collection( results ) ;