Return a Backbone collection when filtering a Collection
In order to filter a Backbone.Collection
, you are maybe doing this:
Collection.filter(/* your filter condition */)
The problem is that the result you get is a simple javascript Array
and not a Backbone.Collection
instance.
There are some case when you'd like to be able to use convenient Collection methods to filtered values.
To achieve this, just wrap the returning object into an Underscore object:
var filtered = _(collection.filter(/* filter condition */));
/* calling a Backbone.Collection method */
console.log(filtered.size())
Not very elegant, but it does do the job.
Written by Simone
Related protips
3 Responses
Your example does not wrap the results in a new Backbone Collection as your title says. Instead it wraps it in an Underscore object, that happens to have a .size() that acts the same as a Backbone Collection's .size() would. To actually wrap the results in a backbone collection you'll need something like this:
var filtered = new Backbone.Collection(collection.filter(function(model) {
return model.get('name').substr(0, 1) === 'b';
}));
For a more generic way you could add this function to your base object, to demonstrate with working code I'll patch it into Backbone.Collection.
Backbone.Collection.prototype.filteredCollection = function(iterator) {
// If you're using a collection that extends Backbone.Collection
// the constructor will give you the same type of object back.
return new this.constructor(this.filter(iterator));
}
Thanks guys, helped me a lot!
The correct way to do this is:
this.collection = this.collection.reset(this.collection.filter(...));
This will create a collection that is the same type as the original.