public
Last active

Monkey patch `Backbone.Model.extend()` with ES5 getters/setters for each attribute defined in the defaults.

  • Download Gist
backbone.model.es5properties.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
/**
* Monkey patch `Backbone.Model.extend()` with ES5 getters/setters for each
* attribute defined in the defaults. Gives you the added bonus of being
* to pass your backbone models directly to your Mustache.js views.
*
* Example:
*
* var User = Backbone.Model.extend({
* defaults: {
* username: undefined,
* email: undefined
* }
* });
*
* // Now, instead of `user.set(...)`, we can user attribute names at properties:
* var user = new User();
* user.username = "dandean"
* user.email = "punch@face.com"
*
* JSON.stringify(user);
* // -> "{"username":"dandean","email":"punch@face.com"}"
**/
 
// Store original Backbone.Model.extend for later use...
var originalBackboneModelExtend = Backbone.Model.extend;
 
// Define a NEW Backbone.Model.extend which will place getters and setters
// for each of our defaults on the model instance prototype...
Backbone.Model.extend = function(parent, protoProps, staticProps) {
// Call the original extend method...
var child = originalBackboneModelExtend.call(Backbone.Model, parent, protoProps, staticProps);
// Swap arguments, if parent wasn't provided...
if (parent instanceof Backbone.Model === false) {
protoProps = parent;
}
 
// If defaults are provided...
if ('defaults' in protoProps) {
Object.keys(protoProps.defaults).forEach(function(name) {
// Unless the property is id...
if (name != 'id') {
// Create the getters and setters for the property...
Object.defineProperty(child.prototype, name, {
// Getter proxies to Model#get()...
get: function() { return this.get(name); },
// Setter proxies to Model#set(attributes)
set: function(value) {
var data = {};
data[name] = value;
this.set(data);
},
// Make it configurable and enumerable so it's easy to override...
configurable: true,
enumerable: true
});
}
});
}
 
// Return the new Model, now with getters and setters for each property!
return child;
};

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.