backbone-relationship
Backbone plugin that coerces attributes to models and collections
This library was built to solve handling relationships in a non-complex manner. We were frustrated at the excess amount of code in existing Backbone relationship libraries. This library focuses on one thing well, "converting objects/arrays to models/collections".
Getting Started
npm
Install the module with: npm install backbone-relationship
// Extend Backbone and add our bindingsvar BackboneRelationship = ;var Backbone = BackboneRelationship; // Define a model with a model relationshipvar LocationModel = BackboneModel;var UserModel = BackboneModel; // Create a user modelvar user = location: city: 'San Francisco' state: 'CA';var location = user; // LocationModel({city: 'San Francisco', state: 'CA'})location; // San Franciscolocation; // San Francisco, CA // Define a model with a collection relationshipvar LocationCollection = BackboneCollection;var UserModel = BackboneModel; // Create a user modelvar user = past_locations: city: 'San Francisco' state: 'CA' city: 'Los Angeles' state: 'CA' ;var locations = user; // LocationCollection([{city: 'San Francisco', state: 'CA'}, ...])locations; // LocationModel({city: 'Los Angeles', state: 'CA'})locations; // Los Angeles, CA
More examples can be found in the Examples section.
bower
Install the module with: bower install backbone-relationship
Vanilla
Download the minified JS at:
Documentation
backbone-relationship
exposes the object BackboneRelationship
as its module.exports
.
BackboneRelationship.mixin(Backbone, _)
Extend Backbone and return Backbone with updated Model
and Collection
classes.
This will not mutate Backbone's Model
and Collection
classes.
- Backbone
Object
- Backbone library to mix into- Model
Function
- Constructor for Backbone models to add new behavior to - Collection
Function
- Constructor for Backbone collections to add new behavior to
- Model
- _
Object
- Underscore library used by Backbone
Returns:
- ExtendedBackbone
Object
- Extension ofBackbone
library passed in with extendedBackbone.Model
andBackbone.Collection
classes
Model.prototype.relationships
Any future models created from our extended Backbone will be allowed to coerce attributes from strings/objects into Models
/Collections
/any constructor.
- relationships
Object
- Container to which attributes to be coerced-
Mixed
- Each key/value pair will be treated as a key to coerce from a model'sattributes
via its value (typically a constructor)- For example, a model with
relationships: {location: LocationModel}
- When we run
.set('location', {name: 'NYC'})
, we will generate aLocationModel({name: 'NYC'})
and save it atmodel.get('location')
- Under the hood,
.set
is run on initialize and any time an attribute is updated
- When we run
- An example with a non-Backbone constructor is a model with
relationships: {created_at: Date}
- When we run
.set('created_at', '2014-01-01')
, we will generate anew Date('2014-01-01')
and save it atmodel.get('created_at')
- When we run
- For example, a model with
-
For more examples, please see the Examples section.
Model/Collection.prototype.inheritedOptions
Any future models/collections created from our extended Backbone will be allowed to pass options to their children.
- inheritedOptions
Array
- Names of options to pass on from parent to child relationship-
String
- Name of option to pass on- For example, a model with
inheritedOptions: ['config'], relationships: {location: LocationModel}
- We will initialize our model via
new UserModel({location: {name: 'NYC}}, {config: 'hello', query: true})
- When we run
.set('location', {name: 'NYC'})
, we will generate aLocationModel({name: 'NYC'}, {conifg: 'hello'})
. This means we will create a new set of options based off of the parent's options to pass through (i.e.{config: 'hello'}
)
- We will initialize our model via
- An example with a collection is
inheritedOptions: ['config'], model: UserModel
- We will initialize our collection via
new UserCollection([{location: {name: 'NYC}}], {config: 'hello', query: true})
- Each of our models in this collection will be initialized via
UserModel(attrs, {conifg: 'hello'})
(e.g.UserModel({location: {name: 'NYC'}}, {conifg: 'hello'})
)
- We will initialize our collection via
- For example, a model with
-
For more examples, please see the Examples section.
Examples
Functions/Constructors
In order to make type coercion easy for some properties (e.g. Date
), we support invoking any function
as if it were a constructor (e.g. Date
, RegExp
). This example provides a few scenarios:
// Extend Backbone and add our bindingsvar BackboneRelationship = ;var Backbone = BackboneRelationship; // Define a model with a Datevar ItemModel = BackboneModel;var item = created_at: '2014-01-01';item; // Date('2014-01-01'); Wed Jan 01 2014 00:00:00 GMT // Define a model with a custom functionvar ItemModel = BackboneModel;var item = tags: 'green,medium';item; // ['green', 'medium']
Inheritance
When using Backbone on the server, it is critical to pass around specific information between inherited models (e.g. external URL for server; underdog.io
). In this example, we will pass through an inherited option from a collection to a model to a submodel to demonstrate the depth of inheritance.
// Extend Backbone and add our bindingsvar BackboneRelationship = ;var Backbone = BackboneRelationship; // Define our models/collectionsvar LocationModel = BackboneModel;var UserModel = BackboneModel;var UserCollection = BackboneCollection; // Create a collection with a configvar users = name: 'Bark Ruffalo' location: name: 'New York City' config: baseUrl: 'https://underdog.io/'; // Verify we have `config` saved on each collection/modelusers_config; // {baseUrl: 'https://underdog.io/'}var user = users; // new UserModel({name: 'Bark Ruffalo', location: ...}, {config: ...})user_config; // {baseUrl: 'https://underdog.io/'}var location = user; // new LocationModel({name: 'New York City'}, {config: ...})location_config; // {baseUrl: 'https://underdog.io/'}
Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint via npm run lint
and test via npm test
.
License
Copyright (c) 2015 Underdog.io
Licensed under the MIT license.