Last Updated: July 25, 2019
·
9.58K
· rjz

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.