Backbone.js 0.9.0
+(c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
Backbone may be freely distributed under the MIT license.
For all details and documentation:
-http://documentcloud.github.com/backbone
-
Turn on emulateHTTP to support legacy HTTP servers. Setting this option will
-fake "PUT" and "DELETE" requests via the _method parameter and set a
-X-Http-Method-Override header.
Turn on emulateHTTP to support legacy HTTP servers. Setting this option
+will fake "PUT" and "DELETE" requests via the _method parameter and
+set a X-Http-Method-Override header.
Turn on emulateJSON to support legacy servers that can't deal with direct
application/json requests ... will encode the body as
application/x-www-form-urlencoded instead and will send the model in a
form param named model.
A module that can be mixed in to any object in order to provide it with
-custom events. You may bind or unbind a callback function to an event;
-trigger-ing an event fires all callbacks in succession.
+custom events. You may bind with on or remove with off callback functions
+to an event; trigger`-ing an event fires all callbacks in succession.
Remove one or many callbacks. If context is null, removes all callbacks
+with that function. If callback is null, removes all callbacks for the
+event. If ev is null, removes all bound callbacks for all events.
Trigger an event, firing all bound callbacks. Callbacks are passed the
same arguments as trigger is, apart from the event name.
-Listening for "all" passes the true event name as the first argument.
trigger:function(eventName){
- varnode,calls,callback,args,ev,events=['all',eventName];
+Listening for "all" passes the true event name as the first argument.
Fetch the model from the server. If the server's representation of the
model differs from its current attributes, they will be overriden,
-triggering a "change" event.
fetch:function(options){
- options||(options={});
+triggering a "change" event.
Set a hash of model attributes, and sync the model to the server.
If the server returns an attributes hash that differs, the model's
-state will be set again.
save:function(attrs,options){
- options||(options={});
- if(attrs&&!this.set(attrs,options))returnfalse;
+state will be set again.
Destroy this model on the server if it was already persisted.
+Optimistically removes the model from its collection, if it has one.
+If wait: true is passed, waits for the server to respond before removal.
Default URL for the model's representation on the server -- if you're
using Backbone's restful methods, override this to change the endpoint
-that will be called.
url:function(){
- varbase=getUrl(this.collection)||this.urlRoot||urlError();
+that will be called.
Call this method to manually fire a "change" event for this model and
+a "change:attribute" event for each changed attribute.
+Calling this will cause all objects observing the model to update.
Return an object containing all the attributes that have changed, or false
-if there are no changed attributes. Useful for determining what parts of a
-view need to be updated and/or what attributes need to be persisted to
-the server. Unset attributes will be set to undefined.
Return an object containing all the attributes that have changed, or
+false if there are no changed attributes. Useful for determining what
+parts of a view need to be updated and/or what attributes need to be
+persisted to the server. Unset attributes will be set to undefined.
+You can also pass an attributes object to diff against the model,
+determining if there would be a change.
Run validation against a set of incoming attributes, returning true
if all is well. If a specific error callback has been passed,
-call that instead of firing the general "error" event.
_performValidation:function(attrs,options){
- varerror=this.validate(attrs);
+call that instead of firing the general "error" event.
Provides a standard collection class for our sets of models, ordered
or unordered. If a comparator is specified, the Collection will maintain
its models in sort order, as they're added and removed.
Begin by turning bare objects into model references, and preventing
+invalid models or duplicate models from being added.
for(i=0,length=models.length;i<length;i++){
+ if(!(model=models[i]=this._prepareModel(models[i],options))){
+ thrownewError("Can't add an invalid model to a collection");}
- }else{
- this._add(models,options);
+ if(cids[cid=model.cid]||this._byCid[cid]||
+ (((id=model.id)!=null)&&(ids[id]||this._byId[id]))){
+ thrownewError("Can't add the same model to a collection twice");
+ }
+ cids[cid]=ids[id]=model;
+ }
Force the collection to re-sort itself. You don't need to call this under normal
-circumstances, as the set will maintain sort order as each item is added.
Force the collection to re-sort itself. You don't need to call this under
+normal circumstances, as the set will maintain sort order as each item
+is added.
sort:function(options){options||(options={});if(!this.comparator)thrownewError('Cannot sort a set without a comparator');
- this.models=this.sortBy(this.comparator);
+ varboundComparator=_.bind(this.comparator,this);
+ if(this.comparator.length==1){
+ this.models=this.sortBy(boundComparator);
+ }else{
+ this.models.sort(boundComparator);
+ }if(!options.silent)this.trigger('reset',this,options);returnthis;
- },
When you have more items than you want to add or remove individually,
you can reset the entire set with a new list of models, without firing
-any added or removed events. Fires reset when finished.
reset:function(models,options){
+any add or remove events. Fires reset when finished.
Fetch the default set of models for this collection, resetting the
collection when they arrive. If add: true is passed, appends the
-models to the collection instead of resetting.
fetch:function(options){
- options||(options={});
+models to the collection instead of resetting.
Create a new instance of a model in this collection. After the model
-has been created on the server, it will be added to the collection.
-Returns the model, or 'false' if validation on a new model fails.
Create a new instance of a model in this collection. Add the model to the
+collection immediately, unless wait: true is passed, in which case we
+wait for the server to agree.
Internal implementation of adding a single model to the set, updating
-hash indexes for id and cid lookups.
-Returns the model, or 'false' if validation on a new model fails.
_add:function(model,options){
- options||(options={});
- model=this._prepareModel(model,options);
- if(!model)returnfalse;
- varalready=this.getByCid(model);
- if(already)thrownewError(["Can't add the same model to a set twice",already.id]);
- this._byId[model.id]=model;
- this._byCid[model.cid]=model;
- varindex=options.at!=null?options.at:
- this.comparator?this.sortedIndex(model,this.comparator):
- this.length;
- this.models.splice(index,0,model);
- model.bind('all',this._onModelEvent);
- this.length++;
- options.index=index;
- if(!options.silent)model.trigger('add',model,this,options);
- returnmodel;
- },
Internal method called every time a model in the set fires an event.
Sets need to update their indexes when models change ids. All other
events simply proxy through. "add" and "remove" events that originate
-in other collections are ignored.
_onModelEvent:function(ev,model,collection,options){
+in other collections are ignored.
Bind all defined routes to Backbone.history. We have to reverse the
order of the routes here to support behavior where the most general
-routes can be defined at the bottom of the route map.
_bindRoutes:function(){
+routes can be defined at the bottom of the route map.
_extractParameters:function(route,fragment){returnroute.exec(fragment).slice(1);}
@@ -472,9 +518,9 @@
browser does not support onhashchange, falls back to polling.
Save a fragment into the hash history, or replace the URL state
-if the 'replace' option is passed. You are responsible for properly
-URL-encoding the fragment in advance. This does not trigger
-a hashchange event.
-parameters:
Save a fragment into the hash history, or replace the URL state if the
+'replace' option is passed. You are responsible for properly URL-encoding
+the fragment in advance.
-
-
fragment: the URL fragment to navigate to (the portion after the '#')
-
options: An object with the following parameters:
- - trigger: call the route corresponding to the provided fragment
- - replace: Navigate such that the back button will
- not return to this current state.
-
-
To comply with earlier API specifications, passing
- true/false for options will be interpretted as
- {options: trigger: true/false}
-
The options object can contain trigger: true if you wish to have the
+route callback be fired (not usually desirable), or replace: true, if
+you which to modify the current URL without adding an entry to the history.
Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
+ this._updateHash(window.location,frag,options.replace);
+ if(this.iframe&&(frag!=this.getFragment(this.iframe.location.hash))){
render is the core function that your view should override, in order
to populate its element (this.el), with the appropriate HTML. The
-convention is for render to always return this.
render:function(){
+convention is for render to always return this.
@@ -631,59 +676,61 @@
Uses event delegation for efficiency.
Omitting the selector binds the event to this.el.
This only works for delegate-able events: not focus, blur, and
-not change, submit, and reset in Internet Explorer.
delegateEvents:function(events){
- if(!(events||(events=this.events)))return;
- if(_.isFunction(events))events=events.call(this);
+not change, submit, and reset in Internet Explorer.
Clears all callbacks previously bound to the view with delegateEvents.
+You usually don't need to use this, but may wish to if you have multiple
+Backbone views attached to the same DOM element.
Performs the initial configuration of a View with a set of options.
Keys with special meaning (model, collection, id, className), are
-attached directly to the view.
_configure:function(options){
+attached directly to the view.
Ensure that the View has a DOM element to render into.
If this.el is a string, pass it through $(), take the first
matching element, and re-assign it to el. Otherwise, create
-an element from the id, className and tagName properties.
_ensureElement:function(){
+an element from the id, className and tagName properties.
Override this function to change the manner in which Backbone persists
models to the server. You will be passed the type of request, and the
model in question. By default, makes a RESTful Ajax request
to the model's url(). Some possible customizations could be:
@@ -696,19 +743,19 @@
Turn on Backbone.emulateHTTP in order to send PUT and DELETE requests
as POST, with a _method parameter containing the true HTTP method,
-as well as all requests with the body as application/x-www-form-urlencoded instead of
-application/json with the model in a param named model.
+as well as all requests with the body as application/x-www-form-urlencoded
+instead of application/json with the model in a param named model.
Useful when interfacing with server-side languages like PHP that make
it difficult to read the body of PUT requests.
Helper function to correctly set up the prototype chain, for subclasses.
Similar to goog.inherits, but uses a hash of prototype properties and
class properties to be extended.
The constructor function for the new subclass is either defined by you
(the "constructor" property in your extend definition), or defaulted
-by us to simply call super().
if(protoProps&&protoProps.hasOwnProperty('constructor')){
+by us to simply call the parent's constructor.
If you hit return in the main input field, and there is text to save,
diff --git a/index.html b/index.html
index d5ce9dcb5..dd5535c43 100644
--- a/index.html
+++ b/index.html
@@ -83,9 +83,16 @@
}
div.container ul {
list-style: circle;
- font-size: 12px;
padding-left: 15px;
+ font-size: 13px;
+ line-height: 18px;
}
+ div.container ul li {
+ margin-bottom: 10px;
+ }
+ div.container ul.small {
+ font-size: 12px;
+ }
a, a:visited {
color: #444;
}
@@ -191,19 +198,23 @@
When working on a web application that involves a lot of JavaScript, one
@@ -469,6 +484,33 @@
Introduction
Many of the examples that follow are runnable. Click the play button
to execute them.
+
+
Upgrading to 0.9
+
+
+ Backbone's 0.9 series should be considered as a release candidate
+ for an upcoming 1.0. Some APIs have changed, and while there is a
+ change log available, and many new features to
+ take advantage of, there are a few specific changes where you'll need
+ to take care:
+
+
+
+
+ If you've ever manually set this.el in a Backbone View to be a
+ particular DOM element, you'll want to use
+ setElement instead.
+
+
+ Creating and destroying models is now optimistic. Pass {wait: true}
+ if you need the previous behavior of waiting for the server to acknowledge
+ success. You can now also pass {wait: true} to save calls.
+
+
+ If you have been writing a fair amount of $(view.el), there's now
+ a cached reference for that jQuery object: $el.
+
among different areas of your application: var dispatcher = _.clone(Backbone.Events)
-
- bindobject.bind(event, callback, [context])
+
+ onobject.on(event, callback, [context])Alias: bind
Bind a callback function to an object. The callback will be invoked
whenever the event (specified by an arbitrary string identifier) is fired.
@@ -507,7 +549,7 @@
Backbone.Events
To supply a context value for this when the callback is invoked,
- pass the optional third argument: model.bind('change', this.render, this)
+ pass the optional third argument: model.on('change', this.render, this)
+ offobject.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, all event callbacks on the object
will be removed.
-object.unbind("change", onChange); // Removes just the onChange callback.
+object.off("change", onChange); // Removes just the onChange callback.
-object.unbind("change"); // Removes all "change" callbacks.
+object.off("change"); // Removes all "change" callbacks.
-object.unbind(); // Removes all callbacks on object.
+object.off(); // Removes all callbacks on object.
change the models state, a "change" event will be triggered, unless
{silent: true} is passed as an option. Change events for specific
attributes are also triggered, and you can bind to those as well, for example:
- change:title, and change:content.
+ change:title, and change:content. You may also pass
+ individual keys and values.
-note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
+note.set({title: "March 20", content: "In his eyes she eclipses..."});
+
+book.set("title", "A Scandal in Bohemia");
@@ -854,12 +901,20 @@
Backbone.Model
hash (as in set) should contain the attributes
you'd like to change — keys that aren't mentioned won't be altered — but,
a complete representation of the resource will be sent to the server.
+ As with set, you may pass individual keys and values instead of a hash.
If the model has a validate
method, and validation fails, the model will not be saved. If the model
isNew, the save will be a "create"
(HTTP POST), if the model already
exists on the server, the save will be an "update" (HTTP PUT).
+
+
+ Calling save with new attributes will cause a "change"
+ event immediately, and a "sync" event after the server has acknowledged
+ the successful change. Pass {wait: true} if you'd like to wait
+ for the server before setting the new attributes on the model.
+
In the following example, notice how our overridden version
@@ -894,7 +949,7 @@
request to Backbone.sync. Accepts
success and error callbacks in the options hash.
Triggers a "destroy" event on the model, which will bubble up
- through any collections that contain it.
+ through any collections that contain it, and a "sync" event, after
+ the server has successfully acknowledged the model's deletion. Pass
+ {wait: true} if you'd like to wait for the server to respond
+ before removing the model from the collection.
Specify a urlRoot if you're using a model outside of a collection,
to enable the default url function to generate
- URLs based on the model id. "/[urlRoot]/id"
+ URLs based on the model id. "/[urlRoot]/id"
+ Note that urlRoot may also be defined as a function.
name: "Bill Smith"
});
-bill.bind("change:name", function(model, name) {
+bill.on("change:name", function(model, name) {
alert("Changed name from " + bill.previous("name") + " to " + name);
});
@@ -1117,7 +1176,7 @@
Backbone.Collection
triggered on the collection directly, for convenience.
This allows you to listen for changes to specific attributes in any
model in a collection, for example:
- Documents.bind("change:selected", ...)
+ Documents.on("change:selected", ...)
@@ -1187,14 +1246,14 @@
Backbone.Collection
- Underscore Methods (26)
+ Underscore Methods (28)
- Backbone proxies to Underscore.js to provide 26 iteration functions
+ Backbone proxies to Underscore.js to provide 28 iteration functions
on Backbone.Collection. They aren't all documented here, but
you can take a look at the Underscore documentation for the full details…
model property is defined, you may also pass
raw attributes objects, and have them be vivified as instances of the model.
Pass {at: index} to splice the model into the collection at the
- specified index.
+ specified index. Likewise, if you're a callback listening to a
+ collection's "add" event, options.index will tell you the
+ index at which the model is being added to the collection.
Remove a model (or an array of models) from the collection. Fires a
"remove" event, which you can use silent
- to suppress.
+ to suppress. If you're a callback listening to the "remove" event,
+ the index at which the model is being removed from the collection is available
+ as options.index.
@@ -1314,8 +1379,20 @@
Backbone.Collection
If you define a comparator, it will be used to maintain
the collection in sorted order. This means that as models are added,
they are inserted at the correct index in collection.models.
- Comparator functions take a model and return a numeric or string value
- by which the model should be ordered relative to others.
+ Comparator function can be defined as either a
+ sortBy
+ (pass a function that takes a single argument),
+ or as a
+ sort
+ (pass a comparator function that expects two arguments).
+
+
+
+ "sort" comparator functions take a model and return a numeric or string
+ value by which the model should be ordered relative to others.
+ "sortBy" comparator functions take two models, and return -1 if
+ the first model should come before the second, 0 if they are of
+ the same rank and 1 if the first model should come after.
@@ -1338,12 +1415,6 @@
Backbone.Collection
alert(chapters.pluck('title'));
-
- Brief aside: This comparator function is different than JavaScript's regular
- "sort", which must return 0, 1, or -1,
- and is more similar to a sortBy — a much nicer API.
-
-
Collections with comparator functions will not automatically re-sort if you
later change model attributes, so you may wish to call sort after
@@ -1410,7 +1481,9 @@
Backbone.Collection
the array of model attributes to be added
to the collection. The default implementation is a no-op, simply passing
through the JSON response. Override this if you need to work with a
- preexisting API, or better namespace your responses.
+ preexisting API, or better namespace your responses. Note that afterwards,
+ if your model class already has a parse function, it will be
+ run against each fetched model.
@@ -1509,6 +1582,13 @@
Backbone.Collection
The create method can accept either an attributes hash or an
existing, unsaved model object.
+
+
+ Creating a model will cause an immediate "add" event to be
+ triggered on the collection, as well as a "sync" event, once the
+ model has been successfully created on the server. Pass {wait: true}
+ if you'd like to wait for the server before adding the new model to the collection.
+
var Library = Backbone.Collection.extend({
@@ -1608,7 +1688,7 @@
- You may assign el directly if the view is being
- created for an element that already exists in the DOM. Use either a
- reference to a real DOM element, or a css selector string.
-
-
var ItemView = Backbone.View.extend({
tagName: 'li'
@@ -1932,6 +2006,35 @@
Backbone.View
alert(item.el + ' ' + body.el);
+
+ $elview.$el
+
+ A cached jQuery (or Zepto) object for the view's element. A handy
+ reference instead of re-wrapping the DOM element all the time.
+
+ setElementview.setElement(element)
+
+ If you'd like to apply a Backbone view to a different DOM element, use
+ setElement, which will also create the cached $el reference
+ and move the view's delegated events from the old element to the new one.
+
+
+
+ attributesview.attributes
+
+ A hash of attributes that will be set as HTML DOM element attributes on the
+ view's el (id, class, data-properties, etc.), or a function that
+ returns such a hash.
+
+
$ (jQuery or Zepto)view.$(selector)
@@ -2027,6 +2130,8 @@
Backbone.View
for DOM events within a view.
If an events hash is not passed directly, uses this.events
as the source. Events are written in the format {"event selector": "callback"}.
+ The callback may be either the name of a method on the view, or a direct
+ function body.
Omitting the selector causes the event to be bound to the view's
root element (this.el). By default, delegateEvents is called
within the View's constructor for you, so if you have a simple events
@@ -2085,6 +2190,13 @@
Backbone.View
});
+
+ undelegateEventsundelegateEvents()
+
+ Removes all of the view's delegated events. Useful if you want to disable
+ or remove a view from the DOM temporarily.
+
+
Utility Functions
@@ -2738,13 +2850,14 @@
F.A.Q.
see fit.
-
+
"add" (model, collection) — when a model is added to a collection.
"remove" (model, collection) — when a model is removed from a collection.
"reset" (collection) — when the collection's entire contents have been replaced.
"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) — when a model is destroyed.
+
"sync" (model, collection) — triggers whenever a model has been successfully synced to the server.
"error" (model, collection) — when a model's validation fails, or a save call fails on the server.
"route:[name]" (router) — when one of a router's routes has matched.
"all" — this special event fires for any triggered event, passing the event name as the first argument.
@@ -2788,8 +2901,8 @@
F.A.Q.
Feel free to define your own events.Backbone.Events
is designed so that you can mix it in to any JavaScript object or prototype.
Since you can use any string as an event, it's often handy to bind
- and trigger your own custom events: model.bind("selected:true") or
- model.bind("editing")
+ and trigger your own custom events: model.on("selected:true") or
+ model.on("editing")
+ Creating and destroying models with create and destroy
+ are now optimistic by default. Pass {wait: true} as an option
+ if you'd like them to wait for a successful server response to proceed.
+
+
+ Two new properties on views: $el — a cached jQuery (or Zepto)
+ reference to the view's element, and setElement, which should
+ be used instead of manually setting a view's el. It will
+ both set view.el and view.$el correctly, as well as
+ re-delegating events on the new DOM element.
+
+
+ When you don't know the key in advance, you may now call
+ model.set(key, value) as well as save.
+
+
+ Multiple models with the same id are no longer allowed in a
+ single collection.
+
+
+ Added a "sync" event, which triggers whenever a model's state
+ has been successfully synced with the server (create, save, destroy).
+
+
+ bind and unbind have been renamed to on
+ and off for clarity, following jQuery's lead.
+ The old names are also still supported.
+
+
+ A Backbone collection's comparator function may now behave
+ either like a sortBy
+ (pass a function that takes a single argument),
+ or like a sort
+ (pass a comparator function that expects two arguments). The comparator
+ function is also now bound by default to the collection — so you
+ can refer to this within it.
+
+
+ A view's events hash may now also contain direct function
+ values as well as the string names of existing view methods.
+
+
+ Added shuffle and initial to collections, proxied
+ from Underscore.
+
+
+ Model#urlRoot may now be defined as a function as well as a
+ value.
+
+
+ View#attributes may now be defined as a function as well as a
+ value.
+
+
+ Calling fetch on a collection will now cause all fetched JSON
+ to be run through the collection's model's parse function, if
+ one is defined.
+
+
+ You may now tell a router to navigate(fragment, {replace: true}),
+ which will either use history.replaceState or
+ location.hash.replace, in order to change the URL without adding
+ a history entry.
+
+
+ Within a collection's add and remove events, the index
+ of the model being added or removed is now available as options.index.
+
+
+ Added an undelegateEvents to views, allowing you to manually
+ remove all configured event delegations.
+
+
+ Although you shouldn't be writing your routes with them in any case —
+ leading slashes (/) are now stripped from routes.
+