Filtering Backbone Collections
Backbone Collections include a bunch of methods for operating on their models, without imposing a particular design pattern on how they are set up or used. It's simultaneously an invigorating breath of fresh air and an invitation to repetition--a persistent enemy of the truly lazy. Fortunately, extracting repeated filtering operations is a fairly simple task.
Take a collection representing the inventory of a store:
var inventory = new InventoryCollection([
{ title: 'Water', value: 5 },
{ title: 'Fruit Juice', value: 10 },
{ title: 'Oil', value: 250 }
]);
As the inventory changes, one common task might be to select all of the inventory items whose value exceeds a certain value. That's easy enough--just use Collection.select
to choose all of the models over the value in question.
// in InventoryCollection
greaterThan: function (value) {
var models = collection.select(function (model) {
return model.get(attribute) > value;
});
return models;
}
It won't do to pass a "naked" array of models to a view that expects a collection, though, so the models will need to be wrapped back up into an instance of the original collection:
greaterThan: function (value) {
// ... select models ...
return new InventoryCollection(models);
}
Generalizing
It isn't hard to imagine wanting to provide the greaterThan
method for other collections. A generalization might accepts arguments for the collection, attribute, and threshold values, using the collection constructor to provide an appropriate return type:
MyApp.greaterThan = function (collection, attribute, value) {
var models = collection.select(function (model) {
return model.get(attribute) > value;
});
return new collection.constructor(models);
};
Rehashing the original example using the new service method:
var newCollection = MyApp.greaterThan(inventory, 'value', 7);
For a more complete implementation (and a bunch of base filters!), checkout the Backbone.Filter repository on github.