Skip to content

Instantly share code, notes, and snippets.

@subimage
Created May 20, 2012 09:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subimage/2757435 to your computer and use it in GitHub Desktop.
Save subimage/2757435 to your computer and use it in GitHub Desktop.
Backbone.js collection 'freshen' method that respects local changes.
Backbone.BaseCollection = Backbone.Collection.extend({
// Holds id of locally deleted items we ignore if we
// 'freshen' the collection and changes haven't propagated yet.
_localDeletedIds: [],
// Take an array of raw objects
// If the ID matches a model in the collection, set that model
// If the ID is not found in the collection, add it
// If a model in the collection is no longer available, remove it
//
// Keeps local changes, in case we've added things in the meantime.
freshen: function(objects) {
var model;
// Mark all for removal, unless local only change
this.each(function(m) {
if (!m.isNew()) m._remove = true;
});
// Apply each object
_(objects).each(function(attrs) {
model = this.get(attrs.id);
if (model) {
model.set(attrs); // existing model
delete model._remove
} else {
// add new models, accounting for local deletions
var locallyDeleted = _.find(this._localDeletedIds,
function(id){ return id == attrs.id });
if (!locallyDeleted) this.add(attrs);
}
}, this);
// Now check for any that are still marked for removal
var toRemove = this.filter(function(m) {
return m._remove;
})
_(toRemove).each(function(m) {
this.remove(m);
}, this);
this.trigger('freshen', this);
},
remove: function(models, options) {
models = _.isArray(models) ? models.slice() : [models];
for (i = 0, l = models.length; i < l; i++) {
if (models[i].id) this._localDeletedIds.push(models[i].id);
}
return Backbone.Collection.prototype.remove.call(this, models, options);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment