Skip to content

Instantly share code, notes, and snippets.

@hongymagic
Last active July 1, 2016 03:34
Show Gist options
  • Save hongymagic/5074695 to your computer and use it in GitHub Desktop.
Save hongymagic/5074695 to your computer and use it in GitHub Desktop.
Turn Backbone.Model accessor methods into property getters/setters. Trash the `get()` and `set()` and use it directly!
(function (Backbone) {
var _old = Backbone.Model;
// Take a Backbone.Model and introduce a proper set of accessors based on
// `defaults`. Instead of having to use accessor methods like `get` and
// `set`, just accesss your model properties:
//
// var user = new User();
// user.name = 'David';
function defineProperty (model, key) {
Object.defineProperty(model, key, {
get: function () { return model.get(key); },
set: function (value) { return model.set(key, value); }
});
}
// In order for this to work, you must declare `defaults` in your model
// definition:
//
// var User = Model.extend({
// defaults: {
// name: null,
// email: null
// }
// });
Backbone.Model = _old.extend({
initialize: function () {
var property;
for (property in this.defaults) {
defineProperty(this, property);
}
}
});
})(Backbone);
<!doctype html>
<html>
<head>
<title>Backbone.Model accessor</title>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<script src="Backbone.Model.js"></script>
<script src="test.js"></script>
</body>
</html>
$(function () {
var User = Backbone.Model.extend({
defaults: {
username: ''
}
});
var user = new User();
user.on('change:username', function (name) {
console.log(this, arguments);
});
user.username = 'hongymagic';
});
@dsheiko
Copy link

dsheiko commented Jan 22, 2016

I would propose to check in defineProperty function if a property has already an accessor method set (to avoid an exception if initialize is called again):

var defineProperty = function( model, key ) {
    var d = Object.getOwnPropertyDescriptor( model, key );
    // If accesors are already set
    if ( d && ( "get" in d || "set" in d ) ) {
      return;
    }
    Object.defineProperty( model, key, {
        get: function () { return model.get( key ); },
        set: function ( value ) { return model.set( key, value ); }
    });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment