Skip to content

Instantly share code, notes, and snippets.

@Dremora
Created January 9, 2015 11:32
Show Gist options
  • Save Dremora/b052655dd1c5c81d7628 to your computer and use it in GitHub Desktop.
Save Dremora/b052655dd1c5c81d7628 to your computer and use it in GitHub Desktop.
groupBy Backbone collection
var Backbone = require('backbone');
var CollectionModel = Backbone.Model.extend({
initialize: function () {
this.collection = new Backbone.Collection();
},
add: function () {
this.collection.add.apply(this.collection, arguments);
},
remove: function () {
this.collection.remove.apply(this.collection, arguments);
},
length: function () {
return this.collection.length;
}
});
return function groupBy (originalCollection, grouping, listener) {
var groups = {};
var models = {};
var collection = new Backbone.Collection();
var addGroup = function (key) {
groups[key] = new CollectionModel();
collection.add(groups[key]);
};
var removeGroup = function (key, group) {
collection.remove(group);
delete groups[key];
};
var add = function (model) {
var key = grouping(model);
if (!groups[key]) {
addGroup(key);
}
var group = groups[key];
group.add(model);
models[model.id] = key;
};
var change = function (model) {
var oldKey = models[model.id];
var newKey = grouping(model);
if (oldKey !== newKey) {
var group = groups[oldKey];
group.remove(model);
if (group.length() === 0) {
removeGroup(oldKey);
}
if (!groups[newKey]) {
addGroup(newKey);
}
groups[newKey].add(model);
models[model.id] = newKey;
}
};
var remove = function (model) {
var key = models[model.id];
var group = groups[key];
group.remove(model);
if (group.length() === 0) {
removeGroup(key);
}
delete models[model.id];
};
originalCollection.each(add);
listener.listenTo(originalCollection, 'add', add);
listener.listenTo(originalCollection, 'change', change);
listener.listenTo(originalCollection, 'remove', remove);
return collection;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment