37:46f343bd26af default tip
Anton Shestakov <av6@dwimlabs.net>, Thu, 05 Jul 2018 22:55:53 +0800
demo: jQuery 3.3.1

previous change 34:36496092e7d7

backbone.shard.js

Permissions: -rw-r--r--

Other formats: Feeds:
/*
* backbone.shard.js.
*
* (c) 2013-2018 Anton Shestakov.
*
* This extension to Backbone may be freely distributed
* under the MIT license:
* https://opensource.org/licenses/MIT
*/
Backbone.Shard = function(options) {
this._collection = options.collection;
this._filter = options.filter;
this.models = this._collection.filter(this._filter);
this._collection
.on('all', function(event, model) {
if (event === 'change') {
if (this._filter(model) && _(this.models).contains(model)) {
this.trigger.apply(this, arguments);
}
if (this._filter(model) && !_(this.models).contains(model)) {
this.models.push(model);
this.trigger('add', model);
}
if (!this._filter(model) && _(this.models).contains(model)) {
this.models = _.without(this.models, model);
this.trigger('remove', model);
}
} else if (/^change:/.test(event) && this._filter(model) && _(this.models).contains(model)) {
this.trigger.apply(this, arguments);
}
}, this)
.on('add', function(model) {
if (this._filter(model) && !_(this.models).contains(model)) {
this.models.push(model);
this.trigger('add', model);
}
}, this)
.on('remove', function(model) {
if (this._filter(model) && _(this.models).contains(model)) {
this.models = _.without(this.models, model);
this.trigger('remove', model);
}
}, this)
.on('reset', function() {
this.models = this._collection.filter(this._filter);
this.trigger('reset');
}, this);
this.initialize.apply(this, arguments);
};
_.extend(Backbone.Shard.prototype, Backbone.Events, {
initialize: function() {},
pluck: function(attr) {
return _.map(this.models, function(model) { return model.get(attr); });
}
});
// Underscore methods that we want to implement on the Shard.
var methods = [
'all', 'any', 'chain', 'chunk', 'collect', 'contains', 'detect',
'difference', 'drop', 'each', 'every', 'filter', 'find', 'findIndex',
'findLastIndex', 'first', 'foldl', 'foldr', 'forEach', 'head', 'include',
'includes', 'indexOf', 'initial', 'inject', 'invoke', 'isEmpty', 'last',
'lastIndexOf', 'map', 'max', 'min', 'partition', 'reduce', 'reduceRight',
'reject', 'rest', 'sample', 'select', 'shuffle', 'size', 'some', 'tail',
'take', 'toArray', 'without'
];
// Mix in each Underscore method as a proxy to `Shard#models`.
_.each(methods, function(method) {
Backbone.Shard.prototype[method] = function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(this.models);
return _[method].apply(_, args);
};
});
// Underscore methods that take a property name as an argument.
var attributeMethods = ['countBy', 'groupBy', 'indexBy', 'sortBy'];
// Use attributes instead of properties.
_.each(attributeMethods, function(method) {
Backbone.Shard.prototype[method] = function(value, context) {
var iterator = _.isFunction(value) ? value : function(model) {
return model.get(value);
};
return _[method](this.models, iterator, context);
};
});