• Stars
    star
    228
  • Rank 174,582 (Top 4 %)
  • Language
    JavaScript
  • Created over 12 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Backbone plugin to override getters and setters with logic

Backbone.Mutators

Backbone plugin to override getters and setters with logic

Build Status, Project Page, Annotated Source & Tests

Build Status Unit Test Status

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

Download

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

// AMD
require(['underscore', 'backbone', 'path/to/backbone.mutators'], function (_, Backbone, Mutators) {
  /* Do stuff with Backbone here */
});

CommonJS

// CommonJS
var _ = require('underscore');
var Backbone = require('backbone');
var Mutators = require('backbone.mutators');

Vanilla JS

<!-- 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>

Usage

Some lines of code explain more then thousand words...

Basic usage

 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'}'

Override getters

 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'}'

Use setters

 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'

Catch model events

 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'

Silence mutator events (while keeping the model events fired)

 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'

Use mutated setters and call the original setter within

 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'

Define one getter / setter method

 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'
    }
 });

Define multiple mutators

 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'
    }
 });

Define a getter as transient

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
    }
  }
});

Further reading

James Brown (@ibjhb) has written a blog article about Mutators (Exploring Backbone.Mutators)

Changelog

0.4.5

  • Extended mutators check #38
  • Allow to specify custom isSaving() method to detect when toJSON() is cal... #36

0.4.4

  • Add mutator dependancies and change events #33

0.4.3

  • Made compatible with browserify #32
  • Backbone dependency version bump #32

0.4.2

0.4.1

0.3.1

  • Change get context to modal instead of attributes
  • Added single getter / setter method

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

  • Initial Release

License

MIT - https://tldrlegal.com/license/mit-license

More Repositories

1

plugin.video.netflix

Inputstream based Netflix plugin for Kodi
Python
1,236
star
2

web-conferences-2018

A list of Web & JavaScript related conferences happening in 2018.
597
star
3

grunt-requirejs

RequireJs (r.js) plugin for grunt.js
JavaScript
300
star
4

grunt-imagine

Grunt tasks for optimizing & inlining images
JavaScript
153
star
5

grunt-patternprimer

Grunting grunts with grunt & serving a pattern catalogue
JavaScript
120
star
6

Backbone.Marionette.Handlebars

Spice up your Backbone.Marionette application with some handlebars flavour
JavaScript
72
star
7

Backbone.Rpc

Backbone.js Plugin for using Json Rpc interfaces
JavaScript
50
star
8

cfp-magick

Show JavaScript and Web conferences with open calls for papers in your terminal
JavaScript
49
star
9

Backbone.Chosen

One Collection, different models, mapped easy via configuration
JavaScript
48
star
10

deepspeech-demo

Demo App for Mozillas DeepSpeech project
JavaScript
16
star
11

serveit2

Quick & dirty static HTTP2 server
JavaScript
15
star
12

grunt-backbonebuilder

Build your customized backbone experience with grunt
JavaScript
14
star
13

grunt-jquerybuilder

Build your customized jquery experience with grunt
JavaScript
11
star
14

grunt-lodashbuilder

Build your Lo-Dash experience with grunt
JavaScript
9
star
15

firefox-element-screenshots

Screenshots single elements from Webpages using Firefox
JavaScript
8
star
16

jsdays-workshop

Demo for the JavaScript Days Workshop 2014
CSS
7
star
17

awb2ics

Abfuhrkalender ICS Generator fรผr AWB Kรถln
JavaScript
7
star
18

webusb-workshop

Learn how to steer POS printers with WebUSB
HTML
7
star
19

sloccount

Counts lines of code of HTML, CSS & JS - Outputs them in a Jenkins compatible format
JavaScript
6
star
20

require-messageformat-plugin

Simple requirejs wrapper around messageformat.js
JavaScript
6
star
21

nightlybuild.io

Page of the Nightlybuild.io conference
HTML
6
star
22

node-homeland

Interface for HM-CFG-USB2 & HM-CFG-LAN as well as an implementation for the BidCos protocol
JavaScript
6
star
23

Backbone.Utils

A few nice snippets around backbone that are not big enough to deserve their own plugin
JavaScript
5
star
24

plugin.video.telekom-sport

Telekom Sport Plugin for Kodi Mediacenter
Python
2
star
25

kodinerds-iptv-proxy

Python
2
star
26

audit-badge

Generates an npm audit badge
JavaScript
2
star
27

about.me

About me
1
star
28

grunt-sloccount

A grunt plugin for generating sloccount compatible reports
JavaScript
1
star
29

asciidisco.com

My blog & site reachable under asciidisco.com (soon)
JavaScript
1
star
30

kodi-release-helper

Kodi Release Helper
Python
1
star
31

grunt-documantix

Creates html doc stuff from docBlock comments
JavaScript
1
star