Skip to content

Instantly share code, notes, and snippets.

@johanneslumpe
Created October 7, 2014 15:15
Show Gist options
  • Save johanneslumpe/f163d62924dd9d29dff9 to your computer and use it in GitHub Desktop.
Save johanneslumpe/f163d62924dd9d29dff9 to your computer and use it in GitHub Desktop.
Model caching
var Backbone = require('backbone');
var _ = require('lodash');
// extend `Backbone.AssociatedModel` with a create method, which will be
// used to create new models for us, instead of using `new`
// shamelessly inspired by Supermodel
var Cached = Backbone.AssociatedModel.extend({
_cached: false,
_ref: 0,
ref: function () {
if (!this._cached) {
this.constructor.cache().add(this);
this._cached = true;
}
this._ref++;
return this;
},
unref: function () {
if(--this._ref <= 0) {
if (this._cached) {
this.constructor.cache().remove(this);
this._cached = false;
}
}
return this;
}
}, {
create: function(attrs, options) {
var cache = this.cache();
var model;
if (attrs && attrs.id) {
model = cache.get(attrs.id);
if (model) {
return model.set(attrs);
}
} else if (_.isString(attrs) || _.isNumber(attrs)) {
model = cache.get(attrs);
if (model) {
return model;
}
}
// if a model has been created using `new` and not using `create`
// and is passed in for a lookup the above check will not return
// a model. in this case we don't want it to be recreated, but instead
// just use the passed in instance
var newModel = (attrs instanceof this) ? attrs : new this(attrs, options);
// newly created models are automatically cached
cache.add(newModel);
newModel._cached = true;
return newModel;
},
cache: function () {
return this._cache || (this._cache = new Backbone.Collection());
}
});
module.exports = Cached;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment