Backbone nested model
Hierarchial data for Backbone models and collections with native javascript syntax.
Features:
- Maintain attributes as hashes rather than model instances
- Access nested instances directly via model.children
- Get nested models using native syntax
- Get children of nested collection using native syntax
- Set nested models using native syntax
- Set collection children using native syntax
- Namespaced change events are emitted from children
- Nested validation
- Nested defaults
The main benefit of this library is that deeply nested models/collection can be addressed as a simple object.
For example:
// This:model// Becomes this:model;// or this:modelproperty;// This:model;// becomes this:model;// or this:model0property;// or this:modelproperty;
Install
npm install backbone-nested-model
Usage
Usage is straightforward - simply define a schema
on your Backbone Model.
The schema is a simple object hash used to cast attributes to the defined types.
A special children
property is created on the model that contains the model/collection instances of the nested children.
var DeepModel =;var model =address:street: '123 shady lane'suburb: ''city: 'Smallville'country: 'USA'postcode: '1234'things:label: 'thing 1'label: 'thing 2';modelattributesaddressstreet === '123 shady lane'; // truemodelattributesaddress instanceof BackboneModel // falsemodelchildrenaddress instanceof BackboneModel // truemodel1label === 'thing 2' // truemodellabel === 'thing 2' // true
Model.get()
The default implementation of Backbone.Model.get()
is overridden to allow access to nested properties using native
javascript syntax. A complete path can be passed as a string: model.get('path.to.property')
- or a partial string
path can be used with the remainder being standard javascript syntax: model.get('path').to.property
.
// ==// Get the attributes of the first item in a nested collection// ==var firstOrder = myModel;// alternatively...var firstOrder = myModel0;// ==// Access a property of the first item in a nested collection// ==var firstOrderDate = myModel;// alternatively...var firstOrderDate = myModeldate;// another way...var firstOrderDate = myModel0date;
Model.set
The default implementation of Backbone.Model.set()
is overridden to allow nested properties to be set directly.
The complete path can be passed as a string: model.set('path.to.property', value)
- or as an object
model.set({ path:{to:{property:value}}})
, or some combination of the two model.set('path.to', { property: value})
.
When dealing with nested collections, individual items can be targeted with the string notation with square brackets:
model.set('myCollection[0]', value)
.
// Set a nested property using dot syntax.model;modelattributesaddressstreet === '321 shady lane'; // truemodelchangedaddressstreet === '321 shady lane'; // truetypeof modelchangedaddresspostcode === 'undefined' // true// Set an individual model in a collectionmodel;modelattributesthingslength === 2; // truemodelattributesthings1label === 'the second thing'; // truemodelchangedthingslength === 1; // true// Reset a collectionmodel;modelchangedthingslength === 2; // 2
Events
Events are emitted when child models are changed or destroyed, with the nested path in the event name like so:
// model will emit 'change:address:street', 'change:address' and 'change' events.model;
Default values
If a models schema defines models with defaults, these child models will not created initially unless either:
- There is an attribute matching the schema key or
- The parent model defines its own defaults hash, with a key matching the schema key.
Validation
If child model implements a validate method, calling validate on the parent will also call the child validate method, returning any errors. This behaviour is also triggered when calling model.save, or model.set({}, {validate: true}).
Tests
There is a full suite of tests in the test directory.
To run the tests, ensure mocha is installed globally: npm install -g mocha
and then npm test
.
To run a code coverage report, ensure mocha and instanbul are installed globally: npm install -g instanbul mocha
and
then run npm run coverage
. The code coverage report can also be viewed in a browser from the coverage directory.