Backbone.Mutators
Backbone plugin to override getters and setters with logic
Build Status, Project Page, Annotated Source & Tests
Project Page
Docs
Tests
NPM registry
Introduction
Ever wanted Backbone to have getters and setters you can override with your own logic?
Yes?! Then Backbone.Mutators is the missing tool in your chain...
Installation
The plugin itself implements the Universal Module Definition (UMD).
You can use it with a CommonJS like loader, or with an AMD loader or via
vanilla javascript.
The plugin has two dependencies, underscore.js and backbone.js
Dowload
You can directly download the
Development Version
or the
Production Version
from the root folder
VOLO
$ volo add Backbone.Mutators
NPM
$ npm install Backbone.Mutators
Integration
AMD
require(['underscore', 'backbone', 'path/to/backbone.mutators'], function (_, Backbone, Mutators) {
});
CommonJS
var _ = require('underscore');
var Backbone = require('backbone');
var Mutators = require('backbone.mutators');
Vanilla JS
<script src="path/to/underscore.js"></script>
<script src="path/to/backbone.js"></script>
<script src="path/to/backbone.mutators.js"></script>
<script>
console.log(Backbone.Mutators);
</script>
Usage
Some lines of code explain more then thousand words...
Basic usage
var User = Backbone.Model.extend({
mutators: {
fullname: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
var user = new User();
user.get('fullname')
user.toJSON()
Override getters
var State = Backbone.Model.extend({
mutators: {
status: function () {
return this.get('status') === true ? 'Workish' : 'Bad bad error';
}
},
defaults: {
status: true
}
});
var state = new State();
state.get('status')
state.toJSON()
Use setters
var User = Backbone.Model.extend({
mutators: {
fullname: {
set: function (key, value, options, set) {
var names = value.split(' ');
this.set('firstname', names[0], options);
this.set('lastname', names[1], options);
},
get: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
var user = new User();
user.set('fullname', 'Big Mama', {silent: true});
user.get('fullname')
user.get('firstname');
user.get('lastname');
Catch model events
var User = Backbone.Model.extend({
mutators: {
fullname: {
set: function (key, value, options, set) {
var names = value.split(' ');
this.set('firstname', names[0], options);
this.set('lastname', names[1], options);
},
get: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
var user = new User();
user.bind('mutators:set:fullname', function () {
console.log('Somebody sets a full name');
});
user.bind('change:firstname', function () {
console.log('Somebody changed the first name');
});
user.bind('change:lastname', function () {
console.log('Somebody changed the last name');
});
user.set('fullname', 'Big Mama');
user.get('fullname')
user.get('firstname');
user.get('lastname');
Silence mutator events (while keeping the model events fired)
var User = Backbone.Model.extend({
mutators: {
fullname: {
set: function (key, value, options, set) {
var names = value.split(' ');
this.set('firstname', names[0], options);
this.set('lastname', names[1], options);
},
get: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
var user = new User();
user.bind('mutators:set:fullname', function () {
console.log('Somebody sets a full name');
});
user.bind('change:firstname', function () {
console.log('Somebody changed the first name');
});
user.bind('change:lastname', function () {
console.log('Somebody changed the last name');
});
user.set('fullname', 'Big Mama', {mutators: {silence: true}});
user.get('fullname')
user.get('firstname');
user.get('lastname');
Use mutated setters and call the original setter within
var Spicy = Backbone.Model.extend({
mutators: {
iAcceptOnlyLowercaseStuff: {
set: function (key, value, options, set) {
set(key, value.toLowerCase(), options);
}
}
},
defaults: {
iAcceptOnlyLowercaseStuff: 'sugar'
}
});
var spicy = new Spicy();
spicy.set('iAcceptOnlyLowercaseStuff', 'SALT');
spicy.get('iAcceptOnlyLowercaseStuff')
Define one getter / setter method
var User = Backbone.Model.extend({
mutators: {
fullname: function (key, value, options, set) {
if(key){
var names = value.split(' ');
this.set('firstname', names[0], options);
this.set('lastname', names[1], options);
}
return this.get('firstname') + ' ' + this.get('lastname');
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
Define multiple mutators
var User = Backbone.Model.extend({
mutators: {
fullname: {
set: function (key, value, options, set) {
var names = value.split(' ');
this.set('firstname', names[0], options);
this.set('lastname', names[1], options);
}
get: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
},
password: function () {
return md5(this.password);
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
Further reading
James Brown (@ibjhb)
has written a blog article about Mutators (Exploring Backbone.Mutators)
Changelog
0.3.1
- Change get context to modal instead of attributes
- Added single getter / setter method
0.3.0
- Removed the Cake based build process and moved to grunt
- Mutators now integrates itself to backbone, no more manual extending needed
- Added the {mutator: {silent: true}} option to prevent mutator set events from firering
- Added unit tests for the new features
- Moved from jslint to jshint
- Tweaked docs
- Removed not needed jquery and qunit-logging submodule / npm dependencies
0.2.0
- Added the original Backbone.Model.set function as a fourth paramter for the mutated set
- Added a 'mutators:set:{{YOUR_MUTATOR_PROPERTY}}' event when setting mutated properties
- Added unit tests for the new features
- Extended/fixed documentation
- Added inline version tag [NOTE: Version 0.2.0 is fully backwards compatible]
0.1.0