Created
May 21, 2012 13:49
-
-
Save jpallen/2762417 to your computer and use it in GitHub Desktop.
Add a .findOrBuild() method to Backbone Models
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Finding and creating models | |
// =========================== | |
// | |
// We might need to get a reference to a model from anywhere in our code | |
// and we want to make sure that these references all point to the same model. | |
// Otherwise updates to one copy of the model won't affect another. | |
// | |
// The methods here let you get models through a wrapper that will either | |
// create the model if it doesn't exist anywhere, or return a reference to | |
// the existing model. E.g. | |
// | |
// var Train = ModelWithFind.extend(); | |
// var thomas = Train.findOrBuild("thomas"); | |
// thomas == Train.findOrBuild("thomas"); // true | |
// thomas == new Train({ "id" : "thomas" }); // false | |
// | |
// Models are looked up by their `id`. If the model doesn't exist yet then it | |
// is created and the attribute given by `idAttribute` is set to the passed value. | |
var ModelWithFind = Backbone.Model.extend({}, { | |
// When trying to get a reference to a model, you should use `findOrBuild`. | |
// This takes one argument which is the model's `id` and will either return the | |
// existing model with that `id` or create it if it doesn't exist. | |
findOrBuild : function(id) { | |
var model = this.find(id); | |
if (model) return model; | |
var options = {}; | |
options[this.prototype.idAttribute] = id; | |
return this.build(options); | |
}, | |
// `build` is a wrapper for the usual `new Model()`. It instantiates the model | |
// but then saves it in the index of loaded models. | |
build : function(options) { | |
var model = new this(options); | |
this.loadedModels = this.loadedModels || {}; | |
this.loadedModels[model.id] = model; | |
// It's possible for a model's id to change. If it does we update our index. | |
var self = this; | |
model.on("change:" + model.idAttribute, function() { | |
self.loadedModels[model.id] = self.loadedModels[model.previous(model.idAttribute)] | |
delete self.loadedModels[model.previous(model.idAttribute)]; | |
}) | |
return model; | |
}, | |
// `find` looks up a model in the index and returns it if it's present. | |
find : function(id) { | |
this.loadedModels = this.loadedModels || {}; | |
return this.loadedModels[id]; | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment