Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Backbone.Mutators
Advanced tools
Backbone plugin to override getters and setters with logic
Project Page
Docs
Tests
NPM registry
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...
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
You can directly download the Development Version or the Production Version from the root folder
$ volo add Backbone.Mutators
$ npm install Backbone.Mutators
// AMD
require(['underscore', 'backbone', 'path/to/backbone.mutators'], function (_, Backbone, Mutators) {
/* Do stuff with Backbone here */
});
// CommonJS
var _ = require('underscore');
var Backbone = require('backbone');
var Mutators = require('backbone.mutators');
<!-- Vanilla javascript -->
<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); // Backbone and the Mutators property are globals
</script>
Some lines of code explain more then thousand words...
var User = Backbone.Model.extend({
// Define mutator properties
mutators: {
fullname: function () {
return this.get('firstname') + ' ' + this.get('lastname');
}
},
defaults: {
firstname: 'Sugar',
lastname: 'Daddy'
}
});
var user = new User();
// use get to get the 'mutated' value
user.get('fullname') // 'Sugar Daddy'
// serialize the model and see the 'mutated' value in the resulting JSON
user.toJSON() // '{firstname: 'Sugar', lastname: 'Daddy', fullname: 'Sugar Daddy'}'
var State = Backbone.Model.extend({
// Define mutator properties
mutators: {
status: function () {
return this.get('status') === true ? 'Workish' : 'Bad bad error';
}
},
defaults: {
status: true
}
});
var state = new State();
// use get to get the 'mutated' value
state.get('status') // 'Workish'
// serialize the model and see the 'mutated' value in the resulting JSON
state.toJSON() // '{status: 'Workish'}'
var User = Backbone.Model.extend({
// Define mutator properties
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();
// use get to get the 'mutated' value
user.set('fullname', 'Big Mama', {silent: true});
// serialize the model and see the 'mutated' value in the resulting JSON
user.get('fullname') // 'Big Mama'
user.get('firstname'); // 'Big'
user.get('lastname'); // 'Mama'
var User = Backbone.Model.extend({
// Define mutator properties
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();
// bind mutator event
user.bind('mutators:set:fullname', function () {
console.log('Somebody sets a full name');
});
// bind model events
user.bind('change:firstname', function () {
console.log('Somebody changed the first name');
});
// bind model events
user.bind('change:lastname', function () {
console.log('Somebody changed the last name');
});
// use get to get the 'mutated' value
user.set('fullname', 'Big Mama');
// serialize the model and see the 'mutated' value in the resulting JSON
user.get('fullname') // 'Big Mama'
user.get('firstname'); // 'Big'
user.get('lastname'); // 'Mama'
var User = Backbone.Model.extend({
// Define mutator properties
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();
// bind mutator event
// will never be run
user.bind('mutators:set:fullname', function () {
console.log('Somebody sets a full name');
});
// bind model events
// will still run
user.bind('change:firstname', function () {
console.log('Somebody changed the first name');
});
// bind model events
// will still run
user.bind('change:lastname', function () {
console.log('Somebody changed the last name');
});
// use get to get the 'mutated' value
user.set('fullname', 'Big Mama', {mutators: {silence: true}});
// serialize the model and see the 'mutated' value in the resulting JSON
user.get('fullname') // 'Big Mama'
user.get('firstname'); // 'Big'
user.get('lastname'); // 'Mama'
var Spicy = Backbone.Model.extend({
// Define mutator properties
mutators: {
iAcceptOnlyLowercaseStuff: {
set: function (key, value, options, set) {
// call the original setter with the lowercased value
set(key, value.toLowerCase(), options);
}
}
},
defaults: {
iAcceptOnlyLowercaseStuff: 'sugar'
}
});
var spicy = new Spicy();
// use get to get the 'mutated' value
spicy.set('iAcceptOnlyLowercaseStuff', 'SALT');
spicy.get('iAcceptOnlyLowercaseStuff') // 'salt'
var User = Backbone.Model.extend({
// Define mutator properties
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'
}
});
var User = Backbone.Model.extend({
// Define mutator properties
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'
}
});
Defining a getter as transient means that it will be omitted when Backbone saves the model. This is
useful if the backend system (whatever Backbone is syncing to) fails if you send it a property that does
not actually exist on the model. Note that this only works for mutators defined with a get()
function.
In the example below, the fullName
property will be available when toJSON is called under
non-syncing circumstances--for example, when providing this model to a template--but will be omitted
from the JSON when sync is called (because you called the sync()
or save()
method), and will not
be sent to the server.
var Model = Backbone.Model.extend({
defaults:{
firstName:"Iain",
middleInit:"M",
lastName:"Banks"
},
mutators:{
fullName:{
get: function() {
var fullName = this.get("firstName");
fullName += " " + this.get("middleInit");
fullName += ". " + this.get("lastName");
return fullName;
},
transient: true
}
}
});
James Brown (@ibjhb) has written a blog article about Mutators (Exploring Backbone.Mutators)
FAQs
Backbone plugin to override getters and setters with logic
We found that Backbone.Mutators demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.