Skip to content

Instantly share code, notes, and snippets.

@mattidupre
Created October 31, 2013 21:51
Show Gist options
  • Select an option

  • Save mattidupre/7257824 to your computer and use it in GitHub Desktop.

Select an option

Save mattidupre/7257824 to your computer and use it in GitHub Desktop.
Backbone loader module that inserts plugins into the Backbone namespace and allows users to insert Model and Collection overrides, default functions. Also adds the ability to translate backbone sync() traffic bidirectionally, useful if your database schema changes but you don't want to rewrite your models.
define([
'backbone'
// add backbone extensions here
], function(Backbone) {
// Declare prototype Backbone.Model functions
var ModelP = {};
// Declare prototype Backbone.Collection functions
var CollectionP = {};
// Declare Backbone.Model functions to override
var ModelF = {};
// Declare Backbone.Collection functions to override
var CollectionF = {};
// Apply prototypes to Backbone
_.extend(Backbone.Model.prototype, ModelP);
_.extend(Backbone.Collection.prototype, CollectionP);
// Replace keys with those in map
var parseIn = function(attr, map, reverse){
_.each(map, function(key1, key2){
if (!reverse){
attr[key2] = attr[key1];
delete attr[key1];
} else {
attr[key1] = attr[key2];
delete attr[key2];
}
});
return attr;
};
// Clone model, replace attribute keys with those in map
var parseOut = function(model, map, reverse){
model = model.clone();
_.each(map, function(key1, key2){
if (!reverse){
model.set(key2, model.get(key1));
model.unset(key1);
} else {
model.set(key1, model.get(key2));
model.unset(key2);
}
});
return model;
};
// Extend Backbone Model methods
var MSync = Backbone.Model.prototype.sync;
var MParse = Backbone.Model.prototype.parse;
_.extend(Backbone.Model.prototype, _.extend({
parse: function(response){
// If translation is provided, parse response
!this.translation || (response = parseIn(response, this.translation));
// Proxy original parse
return CParse(response);
},
sync: function(method, model, options){
// Duplicate model and parse attributes
if (this.translation && model instanceof Backbone.Model){
model = parseOut(model, this.translation, true);
} else if (this.collection && this.collection.translation && model instanceof Backbone.Model){
model = parseOut(model, this.collection.translation, true);
}
// Proxy original sync
MSync(method, model, options);
}
}, ModelP));
// Extend Backbone Collection methods
var CSync = Backbone.Collection.prototype.sync;
var CParse = Backbone.Collection.prototype.parse;
_.extend(Backbone.Collection.prototype, _.extend({
parse: function(response){
// If translation is provided, parse response
if(this.translation){
var translation = this.translation;
_.map(response, function(obj){ return parseIn(obj, translation); });
}
// Proxy original parse
return CParse(response);
},
sync: function(method, collection, options){
// Function to iterate through collection and parse every model
var parse = function(collection, translation){
var collectionOut = new Backbone.Collection();
_.each(collection.models, function(model){
if (model.translation) translation = model.translation;
if (translation) collectionOut.add(parseOut(model, translation, true));
});
return collectionOut;
}
// Duplicate models and parse attributes
if (collection instanceof Backbone.Collection){
var translation = collection.translation || (translation = null);
collection = parse(collection, translation);
}
// Proxy original sync
return CSync(method, collection, options);
}
}, CollectionP));
return Backbone;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment