Reputation: 12401
Is this a good approach to filtering a backbone collection on multiple attributes:
filterData: function(params) {
// store original data for clearing filters
this.originalModels = this.models.slice();
for (var key in params) {
var val = params[key];
// if we are dealing with multiple values in an array
// i.e. ['ford','bmw','mazda']
if (typeof val === "object") {
var union = [];
for (var k in val) {
var subval = val[k];
var matched = _.filter(this.models, function(house) {
return house.get(key) == subval;
});
union = union.concat(matched);
}
this.models = union;
} else {
var results = _.filter(this.models, function(house) {
return house.get(key) == val;
});
this.models = results;
}
} // end for
return this.reset(this.models);
},
clearFilters: function() {
return this.reset(this.originalModels);
}
I tested it and it allows me to filter a collection in the following manner:
filterParams = {brand:['ford','bmw','mazda'], color:black}
carCollection.filterData(filterParams);
It seems to work, but I don't know if there is a better way of doing this.
I tested the Backbone.Collection.where()
method, but it does not work if I want to say brand: ['bmw','mazda','ford']
Upvotes: 4
Views: 2683
Reputation: 161447
You should be able to use something like this:
filterData: function(params) {
// store original data for clearing filters
this.originalModels = this.models.slice();
_.each(params, function(val, key){
if (typeof val !== 'object') val = [ val ];
this.models = _.filter(this.models, function(model){
return _.indexOf(val, model.get(key)) !== -1;
}, this);
}, this);
return this.reset(this.models);
}
Upvotes: 7
Reputation: 16010
Backbone.js collections have access to a number of underscore.js methods, including filter().
carCollection.reset(carCollection.filter(function(car){
return $.inArray(car.brand,['ford','bmw','mazda']) && car.color === 'black';
}));
Not tested, but that should work if you use jQuery. If not, you can create your own inArray() function
Upvotes: 1