Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone filtering

If I have a Backbone collection and want to create a copy of that collection with certain entries filtered out, how can I do that while keeping the copied instance as a Backbone.Collection?

Example:

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/

In the example above, I would like filtered to be a filtered version of modules, not just an array of models.

Essentially I would like to create a method in the collection instance that can filter out certain models and return the Backbone.Collection instance, but as soon as I start filtering the iteration methods returns an array.

like image 554
David Hellsing Avatar asked May 24 '12 16:05

David Hellsing


1 Answers

You can wrap the filtered array in a temporary ModuleCollection if you want, the models filtered are the same instances of the ones in the original ModuleCollection, so if the module's attribute changes, it is still referenced by both collections.

so what I suggest you do is something like:

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

Since Backbone 0.9.2 there is an additional method called where that does the same:

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

that still returns an array though, so you will still need to wrap it as such:

var filtered = new ModuleCollection(modules.where({foo: 'bar'}));
like image 55
Vincent Briglia Avatar answered Sep 28 '22 14:09

Vincent Briglia