Backbone Collection - 构造函数

时间:2013-08-30 11:55:56

标签: backbone.js

我将数组传递给新集合。是否可以通过传递第二个参数来过滤数组,并检查数组中对象的attr,并仅在通过过滤器测试时创建集合。

collection = new Backbone.Collection([{name:'xy',age:24},{name:'y',age:35}])

我是否可以仅为不到30年的对象创建一个集合。

2 个答案:

答案 0 :(得分:5)

在传入集合

之前,您可以在阵列上使用_.filter
collection = new Backbone.Collection(
     _.filter([{name:'xy',age:24},{name:'y',age:35}], 
              function(item) { return item.age < 30; }));

或者您可以将自定义过滤逻辑移动到集合initialize中,您将获得models数组,您可以修改/过滤

var Under30 = Backbone.Collection.extend({
    initialize: function(models, options) {
        for(var i = models.length - 1; i > 0; i-- ){
            if (models[i].age > 30){
                models.splice(i,1);
            }
        }
    }
});

var collection = new Under30([{name:'xy',age:24}, {name:'y',age:35}]);
console.log(collection.models.length); // will be 1

演示JSFiddle

您可以通过在options参数

中提供过滤谓词来扩展它
var FilteredCollection = Backbone.Collection.extend({
        initialize: function(models, options) {
            for(var i = models.length - 1; i > 0; i-- ){
                if (options.filter && options.filter(models[i])){
                    models.splice(i,1);
                }
            }
        }
    });

并与

一起使用
var collection = new FilteredCollection(
      [{name:'xy',age:24}, {name:'y',age:35}], 
      {
          filter: function(item) { 
              return item.age > 30; 
          }
      }
);
console.log(collection.models.length); // will be 1

答案 1 :(得分:1)

更新

您在创建集合之前对验证感兴趣,就像之前的答案一样 - 我们将创建一个函数,让您可以重用该策略,根据您喜欢的条件验证任何集合。

//A collection that validates the correctness of the given elements
// based on a predicate (condition). If the items do not _all_ pass
// the condition - the collection will not be created and an error will
// be thrown.
function validatingCollection(predicate){
    return function(arr){
        //first we assert an array is passed if it's possible to assert
        if(Array.isArray && !Array.isArray(arr)){
            throw new Error("Can only pass array to filteredCollection");
        }
        //for older browsers - use _.every 
        // now we validate they all pass the condition
        if(!arr.every(predicate){
            throw new Error("Validation error, not all elements pass");
        }
        //they all pass, create the collection
        return new Backbone.Collection(arr);
    };
};

现在,我们可以创建一个集合,验证每个元素的年龄至少为30:

var ageValidated = validatedCollection(function(obj){ return obj.age < 30; });
//create a new age validatedcollection
try{
    var collection = new ageValidated([{name:'xy',age:24},{name:'y',age:35}]); 
}catch(e){
    // the above throws an error because of the object with age 24
}
//however - this works, and creates a new collection
var collection = new ageValidated([{name:'xy',age:32},{name:'y',age:35}]); 

如果你只想过滤你不喜欢的元素 - 如果不是所有元素都通过验证而不是抛出错误,你可以这样做:

collection = new Backbone.Collection([{name:'xy',age:24},
                                      {name:'y',age:35}].filter(function(obj){
                                          return obj.age < 30;
                                      });

或者,您可以创建自己的过滤集合构造函数,以便重复使用

function filteredCollection(predicate){
    return function(arr){
        //first we assert an array is passed if it's possible to assert
        if(Array.isArray && !Array.isArray(arr)){
            throw new Error("Can only pass array to filteredCollection");
        }
        return new Backbone.Collection(arr.filter(predicate));
    };
};

让我们这样做:

var ageFilter = filteredCollection(function(obj){ return obj.age < 30; });
    //create a new age collection
var collection = new ageFilter([{name:'xy',age:24},{name:'y',age:35}]); 

另一个答案建议_.filter超过原生Array.filter,如果你必须支持旧的浏览器,这可能是有益的。