UNPKG

backbone-filtered-collection

Version:

Create a filtered version of a backbone collection that stays in sync.

82 lines (70 loc) 2.22 kB
var _ = require('underscore'); // Converts a key and value into a function that accepts a model // and returns a boolean. function convertKeyValueToFunction(key, value) { return function(model) { return model.get(key) === value; }; } // Converts a key and an associated filter function into a function // that accepts a model and returns a boolean. function convertKeyFunctionToFunction(key, fn) { return function(model) { return fn(model.get(key)); }; } function createFilterObject(filterFunction, keys) { // Make sure the keys value is either an array or null if (!_.isArray(keys)) { keys = null; } return { fn: filterFunction, keys: keys }; } // Accepts an object in the form of: // // { // key: value, // key: function(val) { ... } // } // // and turns it into a function that accepts a model an returns a // boolean + a list of the keys that the function depends on. function createFilterFromObject(filterObj) { var keys = _.keys(filterObj); var filterFunctions = _.map(keys, function(key) { var val = filterObj[key]; if (_.isFunction(val)) { return convertKeyFunctionToFunction(key, val); } return convertKeyValueToFunction(key, val); }); // Iterate through each of the generated filter functions. If any // are false, kill the computation and return false. The function // is only true if all of the subfunctions are true. var filterFunction = function(model) { for (var i = 0; i < filterFunctions.length; i++) { if (!filterFunctions[i](model)) { return false; } } return true; }; return createFilterObject(filterFunction, keys); } // Expects one of the following: // // - A filter function that accepts a model + (optional) array of // keys to listen to changes for or null) // - An object describing a filter function createFilter(filter, keys) { // This must go first because _.isObject(fn) === true if (_.isFunction(filter)) { return createFilterObject(filter, keys); } // If the filter is an object describing a filter, generate the // appropriate function. if (_.isObject(filter)) { return createFilterFromObject(filter); } } module.exports = createFilter;