The project is hosted on GitHub, and the annotated source code is available, as well as an online test suite, an example application, a list of tutorials and a long list of real-world projects that use Backbone. Backbone is available for use under the MIT software license.
You can report bugs and discuss features on the GitHub issues page, on Freenode IRC in the #documentcloud channel, post questions to the Google Group, add pages to the wiki or send tweets to @documentcloud.
Backbone is an open-source component of DocumentCloud.
Downloads & Dependencies (Right-click, and use "Save As")
| Development Version (1.3.3) | 72kb, Full source, tons of comments |
| Production Version (1.3.3) |
7.6kb, Packed and gzipped (Source Map) |
| Edge Version (master) |
Unreleased, use at your own risk
|
Getting Started
When working on a web application that involves a lot of JavaScript, one of the first things you learn is to stop tying your data to the DOM. It's all too easy to create JavaScript applications that end up as tangled piles of jQuery selectors and callbacks, all trying frantically to keep data in sync between the HTML UI, your JavaScript logic, and the database on your server. For rich client-side applications, a more structured approach is often helpful.With Backbone, you represent your data as Models, which can be created, validated, destroyed, and saved to the server. Whenever a UI action causes an attribute of a model to change, the model triggers a "change" event; all the Views that display the model's state can be notified of the change, so that they are able to respond accordingly, re-rendering themselves with the new information. In a finished Backbone app, you don't have to write the glue code that looks into the DOM to find an element with a specific id, and update the HTML manually — when the model changes, the views simply update themselves.
Philosophically, Backbone is an attempt to discover the minimal set of data-structuring (models and collections) and user interface (views and URLs) primitives that are generally useful when building web applications with JavaScript. In an ecosystem where overarching, decides-everything-for-you frameworks are commonplace, and many libraries require your site to be reorganized to suit their look, feel, and default behavior — Backbone should continue to be a tool that gives you the freedom to design the full experience of your web application.
If you're new here, and aren't yet quite sure what Backbone is for, start by browsing the list of Backbone-based projects.
Many of the code examples in this documentation are runnable, because Backbone is included on this page. Click the play button to execute them.
Models and Views
Model
- Orchestrates data and business logic.
- Loads and saves from the server.
- Emits events when data changes.
View
- Listens for changes and renders UI.
- Handles user input and interactivity.
- Sends captured input to the model.
A View is an atomic chunk of user interface. It often renders the data from a specific model, or number of models — but views can also be data-less chunks of UI that stand alone. Models should be generally unaware of views. Instead, views listen to the model "change" events, and react or re-render themselves appropriately.
Collections
API Integration
Backbone is pre-configured to sync with a RESTful API. Simply create a new Collection with the url of your resource endpoint:var Books = Backbone.Collection.extend({
url: '/books'
});
The Collection and Model components together form a direct
mapping of REST resources using the following methods:
GET /books/ .... collection.fetch(); POST /books/ .... collection.create(); GET /books/1 ... model.fetch(); PUT /books/1 ... model.save(); DEL /books/1 ... model.destroy();When fetching raw JSON data from an API, a Collection will automatically populate itself with data formatted as an array, while a Model will automatically populate itself with data formatted as an object:
[{"id": 1}] ..... populates a Collection with one model.
{"id": 1} ....... populates a Model with one attribute.
However, it's fairly common to encounter APIs that return data in a
different format than what Backbone expects. For example, consider
fetching a Collection from an API that returns the real data
array wrapped in metadata:
{
"page": 1,
"limit": 10,
"total": 2,
"books": [
{"id": 1, "title": "Pride and Prejudice"},
{"id": 4, "title": "The Great Gatsby"}
]
}
In the above example data, a Collection should populate using the
"books" array rather than the root object structure. This
difference is easily reconciled using a parse method that
returns (or transforms) the desired portion of API data:
var Books = Backbone.Collection.extend({
url: '/books',
parse: function(data) {
return data.books;
}
});
View Rendering
Backbone remains unopinionated about the process used to render View objects and their subviews into UI: you define how your models get translated into HTML (or SVG, or Canvas, or something even more exotic). It could be as prosaic as a simple Underscore template, or as fancy as the React virtual DOM. Some basic approaches to rendering views can be found in the Backbone primer.
Routing with URLs
Backbone.Events
Events is a module that can be mixed in to any object, giving the object the ability to bind and trigger custom named events. Events do not have to be declared before they are bound, and may take passed arguments. For example:var object = {};
_.extend(object, Backbone.Events);
object.on("alert", function(msg) {
alert("Triggered " + msg);
});
object.trigger("alert", "an event");
For example, to make a handy event dispatcher that can coordinate events
among different areas of your application: var dispatcher = _.clone(Backbone.Events)
on
Bind a callback function to an object. The callback will be invoked whenever the event is fired. If you have a large number of different events on a page, the convention is to use colons to namespace them: "poll:start", or "change:selection". The event string may also be a space-delimited list of several events...
object.on(event, callback, [context])Alias: bind
Bind a callback function to an object. The callback will be invoked whenever the event is fired. If you have a large number of different events on a page, the convention is to use colons to namespace them: "poll:start", or "change:selection". The event string may also be a space-delimited list of several events...
book.on("change:title change:author", ...);
Callbacks bound to the special
"all" event will be triggered when any event occurs, and are passed
the name of the event as the first argument. For example, to proxy all events
from one object to another:
proxy.on("all", function(eventName) {
object.trigger(eventName);
});
All Backbone event methods also support an event map syntax, as an alternative
to positional arguments:
book.on({
"change:author": authorPane.update,
"change:title change:subtitle": titleView.update,
"destroy": bookView.remove
});
To supply a context value for this when the callback is invoked,
pass the optional last argument: model.on('change', this.render, this) or
model.on({change: this.render}, this).
off
Remove a previously-bound callback function from an object. If no context is specified, all of the versions of the callback with different contexts will be removed. If no callback is specified, all callbacks for the event will be removed. If no event is specified, callbacks for all events will be removed.
object.off([event], [callback], [context])Alias: unbind
Remove a previously-bound callback function from an object. If no context is specified, all of the versions of the callback with different contexts will be removed. If no callback is specified, all callbacks for the event will be removed. If no event is specified, callbacks for all events will be removed.
// Removes just the `onChange` callback.
object.off("change", onChange);
// Removes all "change" callbacks.
object.off("change");
// Removes the `onChange` callback for all events.
object.off(null, onChange);
// Removes all callbacks for `context` for all events.
object.off(null, null, context);
// Removes all callbacks on `object`.
object.off();
Note that calling model.off(), for example, will indeed remove all events
on the model — including events that Backbone uses for internal bookkeeping.
trigger
Trigger callbacks for the given event, or space-delimited list of events. Subsequent arguments to trigger will be passed along to the event callbacks.
object.trigger(event, [*args])
Trigger callbacks for the given event, or space-delimited list of events. Subsequent arguments to trigger will be passed along to the event callbacks.
once
Just like on, but causes the bound callback to fire only once before being removed. Handy for saying "the next time that X happens, do this". When multiple events are passed in using the space separated syntax, the event will fire once for every event you passed in, not once for a combination of all events
object.once(event, callback, [context])
Just like on, but causes the bound callback to fire only once before being removed. Handy for saying "the next time that X happens, do this". When multiple events are passed in using the space separated syntax, the event will fire once for every event you passed in, not once for a combination of all events
listenTo
Tell an object to listen to a particular event on an other object. The advantage of using this form, instead of other.on(event, callback, object), is that listenTo allows the object to keep track of the events, and they can be removed all at once later on. The callback will always be called with object as context.
object.listenTo(other, event, callback)
Tell an object to listen to a particular event on an other object. The advantage of using this form, instead of other.on(event, callback, object), is that listenTo allows the object to keep track of the events, and they can be removed all at once later on. The callback will always be called with object as context.
view.listenTo(model, 'change', view.render);
stopListening
Tell an object to stop listening to events. Either call stopListening with no arguments to have the object remove all of its registered callbacks ... or be more precise by telling it to remove just the events it's listening to on a specific object, or a specific event, or just a specific callback.
object.stopListening([other], [event], [callback])
Tell an object to stop listening to events. Either call stopListening with no arguments to have the object remove all of its registered callbacks ... or be more precise by telling it to remove just the events it's listening to on a specific object, or a specific event, or just a specific callback.
view.stopListening(); view.stopListening(model);
listenToOnce
Just like listenTo, but causes the bound callback to fire only once before being removed.
object.listenToOnce(other, event, callback)
Just like listenTo, but causes the bound callback to fire only once before being removed.
Catalog of Events
Here's the complete list of built-in Backbone events, with arguments. You're also free to trigger your own events on Models, Collections and Views as you see fit. The Backbone object itself mixes in Events, and can be used to emit any global events that your application needs.
Here's the complete list of built-in Backbone events, with arguments. You're also free to trigger your own events on Models, Collections and Views as you see fit. The Backbone object itself mixes in Events, and can be used to emit any global events that your application needs.
- "add" (model, collection, options) — when a model is added to a collection.
- "remove" (model, collection, options) — when a model is removed from a collection.
- "update" (collection, options) — single event triggered after any number of models have been added or removed from a collection.
- "reset" (collection, options) — when the collection's entire contents have been reset.
- "sort" (collection, options) — when the collection has been re-sorted.
- "change" (model, options) — when a model's attributes have changed.
- "change:[attribute]" (model, value, options) — when a specific attribute has been updated.
- "destroy" (model, collection, options) — when a model is destroyed.
- "request" (model_or_collection, xhr, options) — when a model or collection has started a request to the server.
- "sync" (model_or_collection, response, options) — when a model or collection has been successfully synced with the server.
- "error" (model_or_collection, response, options) — when a model's or collection's request to the server has failed.
- "invalid" (model, error, options) — when a model's validation fails on the client.
- "route:[name]" (params) — Fired by the router when a specific route is matched.
- "route" (route, params) — Fired by the router when any route has been matched.
- "route" (router, route, params) — Fired by history when any route has been matched.
- "all" — this special event fires for any triggered event, passing the event name as the first argument followed by all trigger arguments.
Backbone.Model
Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes.The following is a contrived example, but it demonstrates defining a model with a custom method, setting an attribute, and firing an event keyed to changes in that specific attribute. After running this code once, sidebar will be available in your browser's console, so you can play around with it.
var Sidebar = Backbone.Model.extend({
promptColor: function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color: cssColor});
}
});
window.sidebar = new Sidebar;
sidebar.on('change:color', function(model, color) {
$('#sidebar').css({background: color});
});
sidebar.set({color: 'white'});
sidebar.promptColor();
extend
To create a Model class of your own, you extend Backbone.Model and provide instance properties, as well as optional classProperties to be attached directly to the constructor function.
extend correctly sets up the prototype chain, so subclasses created
with extend can be further extended and subclassed as far as you like.
Backbone.Model.extend(properties, [classProperties])
To create a Model class of your own, you extend Backbone.Model and provide instance properties, as well as optional classProperties to be attached directly to the constructor function.
var Note = Backbone.Model.extend({
initialize: function() { ... },
author: function() { ... },
coordinates: function() { ... },
allowedToEdit: function(account) {
return true;
}
});
var PrivateNote = Note.extend({
allowedToEdit: function(account) {
return account.owns(this);
}
});
Brief aside on super: JavaScript does not provide
a simple way to call super — the function of the same name defined
higher on the prototype chain. If you override a core function like
set, or save, and you want to invoke the
parent object's implementation, you'll have to explicitly call it, along these lines:
var Note = Backbone.Model.extend({
set: function(attributes, options) {
Backbone.Model.prototype.set.apply(this, arguments);
...
}
});
constructor / initialize
When creating an instance of a model, you can pass in the initial values of the attributes, which will be set on the model. If you define an initialize function, it will be invoked when the model is created.
new Model([attributes], [options])
When creating an instance of a model, you can pass in the initial values of the attributes, which will be set on the model. If you define an initialize function, it will be invoked when the model is created.
new Book({
title: "One Thousand and One Nights",
author: "Scheherazade"
});
In rare cases, if you're looking to get fancy,
you may want to override constructor, which allows
you to replace the actual constructor function for your model.
var Library = Backbone.Model.extend({
constructor: function() {
this.books = new Books();
Backbone.Model.apply(this, arguments);
},
parse: function(data, options) {
this.books.reset(data.books);
return data.library;
}
});
If you pass a {collection: ...} as the options, the model
gains a collection property that will be used to indicate which
collection the model belongs to, and is used to help compute the model's
url. The model.collection property is
normally created automatically when you first add a model to a collection.
Note that the reverse is not true, as passing this option to the constructor
will not automatically add the model to the collection. Useful, sometimes.
If {parse: true} is passed as an option, the attributes will first be converted by parse before being set on the model.
get
Get the current value of an attribute from the model. For example: note.get("title")
model.get(attribute)
Get the current value of an attribute from the model. For example: note.get("title")
set
Set a hash of attributes (one or many) on the model. If any of the attributes change the model's state, a "change" event will be triggered on the model. Change events for specific attributes are also triggered, and you can bind to those as well, for example: change:title, and change:content. You may also pass individual keys and values.
model.set(attributes, [options])
Set a hash of attributes (one or many) on the model. If any of the attributes change the model's state, a "change" event will be triggered on the model. Change events for specific attributes are also triggered, and you can bind to those as well, for example: change:title, and change:content. You may also pass individual keys and values.
note.set({title: "March 20", content: "In his eyes she eclipses..."});
book.set("title", "A Scandal in Bohemia");
escape
Similar to get, but returns the HTML-escaped version of a model's attribute. If you're interpolating data from the model into HTML, using escape to retrieve attributes will prevent XSS attacks.
model.escape(attribute)
Similar to get, but returns the HTML-escaped version of a model's attribute. If you're interpolating data from the model into HTML, using escape to retrieve attributes will prevent XSS attacks.
var hacker = new Backbone.Model({
name: "<script>alert('xss')</script>"
});
alert(hacker.escape('name'));
has
Returns true if the attribute is set to a non-null or non-undefined value.
model.has(attribute)
Returns true if the attribute is set to a non-null or non-undefined value.
if (note.has("title")) {
...
}
unset
Remove an attribute by deleting it from the internal attributes hash. Fires a "change" event unless silent is passed as an option.
model.unset(attribute, [options])
Remove an attribute by deleting it from the internal attributes hash. Fires a "change" event unless silent is passed as an option.
Source : http://backbonejs.org/