/ch12/index.html
HTML | 2277 lines | 1955 code | 322 blank | 0 comment | 0 complexity | 3caa4075b2c7b6ef13c2f511e0159302 MD5 | raw file
Possible License(s): JSON
1<!DOCTYPE HTML>
2<html>
3<head>
4 <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
5 <meta http-equiv="X-UA-Compatible" content="chrome=1">
6 <title>Backbone.js</title>
7 <style>
8 body {
9 font-size: 14px;
10 line-height: 22px;
11 font-family: Helvetica Neue, Helvetica, Arial;
12 background: #f4f4f4 url(docs/images/background.png);
13 }
14 .interface {
15 font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important;
16 }
17 div#sidebar {
18 background: #fff;
19 position: fixed;
20 top: 0; left: 0; bottom: 0;
21 width: 200px;
22 overflow-y: auto;
23 overflow-x: hidden;
24 padding: 15px 0 30px 30px;
25 border-right: 1px solid #ddd;
26 box-shadow: 0 0 20px #ccc; -webkit-box-shadow: 0 0 20px #ccc; -moz-box-shadow: 0 0 20px #ccc;
27 }
28 a.toc_title, a.toc_title:visited {
29 display: block;
30 color: black;
31 font-weight: bold;
32 margin-top: 15px;
33 }
34 a.toc_title:hover {
35 text-decoration: underline;
36 }
37 #sidebar .version {
38 font-size: 10px;
39 font-weight: normal;
40 }
41 ul.toc_section {
42 font-size: 11px;
43 line-height: 14px;
44 margin: 5px 0 0 0;
45 padding-left: 0px;
46 list-style-type: none;
47 font-family: Lucida Grande;
48 }
49 .toc_section li {
50 cursor: pointer;
51 margin: 0 0 3px 0;
52 }
53 .toc_section li a {
54 text-decoration: none;
55 color: black;
56 }
57 .toc_section li a:hover {
58 text-decoration: underline;
59 }
60 div.container {
61 position: relative;
62 width: 550px;
63 margin: 40px 0 50px 260px;
64 }
65 div.run {
66 position: absolute;
67 right: 15px;
68 width: 26px; height: 18px;
69 background: url('docs/images/arrows.png') no-repeat -26px 0;
70 }
71 div.run:active {
72 background-position: -51px 0;
73 }
74 p, div.container ul {
75 margin: 20px 0;
76 width: 550px;
77 }
78 p.warning {
79 font-size: 12px;
80 line-height: 18px;
81 font-style: italic;
82 }
83 div.container ul {
84 list-style: circle;
85 font-size: 12px;
86 padding-left: 15px;
87 }
88 a, a:visited {
89 color: #444;
90 }
91 a:active, a:hover {
92 color: #000;
93 }
94 a img {
95 border: 0;
96 }
97 h1, h2, h3, h4, h5, h6 {
98 padding-top: 20px;
99 }
100 h2 {
101 font-size: 20px;
102 }
103 b.header {
104 font-size: 16px;
105 line-height: 30px;
106 }
107 span.alias {
108 font-size: 14px;
109 font-style: italic;
110 margin-left: 20px;
111 }
112 table {
113 margin: 15px 0 0; padding: 0;
114 }
115 tr, td {
116 margin: 0; padding: 0;
117 }
118 td {
119 padding: 0px 15px 5px 0;
120 }
121 code, pre, tt {
122 font-family: Monaco, Consolas, "Lucida Console", monospace;
123 font-size: 12px;
124 line-height: 18px;
125 font-style: normal;
126 }
127 tt {
128 padding: 0px 3px;
129 background: #fff;
130 border: 1px solid #ddd;
131 zoom: 1;
132 }
133 code {
134 margin-left: 20px;
135 }
136 pre {
137 font-size: 12px;
138 padding: 2px 0 2px 15px;
139 border: 4px solid #bbb; border-top: 0; border-bottom: 0;
140 margin: 0px 0 30px;
141 }
142 img.example_image {
143 margin: 0px auto 30px;
144 }
145 </style>
146</head>
147<body>
148
149 <div id="sidebar" class="interface">
150
151 <a class="toc_title" href="#">
152 Backbone.js <span class="version">(0.3.3)</span>
153 </a>
154
155 <a class="toc_title" href="#Introduction">
156 Introduction
157 </a>
158
159 <a class="toc_title" href="#Events">
160 Events
161 </a>
162 <ul class="toc_section">
163 <li>– <a href="#Events-bind">bind</a></li>
164 <li>– <a href="#Events-unbind">unbind</a></li>
165 <li>– <a href="#Events-trigger">trigger</a></li>
166 </ul>
167
168 <a class="toc_title" href="#Model">
169 Model
170 </a>
171 <ul class="toc_section">
172 <li>– <a href="#Model-extend">extend</a></li>
173 <li>– <a href="#Model-constructor">constructor / initialize</a></li>
174 <li>– <a href="#Model-get">get</a></li>
175 <li>– <a href="#Model-set">set</a></li>
176 <li>– <a href="#Model-escape">escape</a></li>
177 <li>– <a href="#Model-has">has</a></li>
178 <li>– <a href="#Model-unset">unset</a></li>
179 <li>– <a href="#Model-clear">clear</a></li>
180 <li>– <a href="#Model-id">id</a></li>
181 <li>– <a href="#Model-cid">cid</a></li>
182 <li>– <a href="#Model-attributes">attributes</a></li>
183 <li>– <a href="#Model-defaults">defaults</a></li>
184 <li>- <a href="#Model-toJSON">toJSON</a></li>
185 <li>– <a href="#Model-fetch">fetch</a></li>
186 <li>– <a href="#Model-save">save</a></li>
187 <li>– <a href="#Model-destroy">destroy</a></li>
188 <li>– <a href="#Model-validate">validate</a></li>
189 <li>– <a href="#Model-url">url</a></li>
190 <li>– <a href="#Model-urlRoot">urlRoot</a></li>
191 <li>– <a href="#Model-parse">parse</a></li>
192 <li>– <a href="#Model-clone">clone</a></li>
193 <li>– <a href="#Model-isNew">isNew</a></li>
194 <li>– <a href="#Model-change">change</a></li>
195 <li>– <a href="#Model-hasChanged">hasChanged</a></li>
196 <li>– <a href="#Model-changedAttributes">changedAttributes</a></li>
197 <li>– <a href="#Model-previous">previous</a></li>
198 <li>– <a href="#Model-previousAttributes">previousAttributes</a></li>
199 </ul>
200
201 <a class="toc_title" href="#Collection">
202 Collection
203 </a>
204 <ul class="toc_section">
205 <li>– <a href="#Collection-extend">extend</a></li>
206 <li>– <a href="#Collection-model">model</a></li>
207 <li>– <a href="#Collection-constructor">constructor / initialize</a></li>
208 <li>– <a href="#Collection-models">models</a></li>
209 <li>– <a href="#Collection-toJSON">toJSON</a></li>
210 <li>– <a href="#Collection-Underscore-Methods"><b>Underscore Methods (25)</b></a></li>
211 <li>– <a href="#Collection-add">add</a></li>
212 <li>– <a href="#Collection-remove">remove</a></li>
213 <li>– <a href="#Collection-get">get</a></li>
214 <li>– <a href="#Collection-getByCid">getByCid</a></li>
215 <li>– <a href="#Collection-at">at</a></li>
216 <li>– <a href="#Collection-length">length</a></li>
217 <li>– <a href="#Collection-comparator">comparator</a></li>
218 <li>– <a href="#Collection-sort">sort</a></li>
219 <li>– <a href="#Collection-pluck">pluck</a></li>
220 <li>– <a href="#Collection-url">url</a></li>
221 <li>– <a href="#Collection-parse">parse</a></li>
222 <li>– <a href="#Collection-fetch">fetch</a></li>
223 <li>– <a href="#Collection-refresh">refresh</a></li>
224 <li>– <a href="#Collection-create">create</a></li>
225 </ul>
226
227 <a class="toc_title" href="#Controller">
228 Controller
229 </a>
230 <ul class="toc_section">
231 <li>– <a href="#Controller-extend">extend</a></li>
232 <li>– <a href="#Controller-routes">routes</a></li>
233 <li>– <a href="#Controller-constructor">constructor / initialize</a></li>
234 <li>– <a href="#Controller-route">route</a></li>
235 <li>– <a href="#Controller-saveLocation">saveLocation</a></li>
236 </ul>
237
238 <a class="toc_title" href="#History">
239 History
240 </a>
241 <ul class="toc_section">
242 <li>– <a href="#History-start">start</a></li>
243 </ul>
244
245 <a class="toc_title" href="#Sync">
246 Sync
247 </a>
248 <ul class="toc_section">
249 <li>– <a href="#Sync">Backbone.sync</a></li>
250 <li>– <a href="#Sync-emulateHTTP">Backbone.emulateHTTP</a></li>
251 <li>– <a href="#Sync-emulateJSON">Backbone.emulateJSON</a></li>
252 </ul>
253
254 <a class="toc_title" href="#View">
255 View
256 </a>
257 <ul class="toc_section">
258 <li>– <a href="#View-extend">extend</a></li>
259 <li>– <a href="#View-constructor">constructor / initialize</a></li>
260 <li>– <a href="#View-el">el</a></li>
261 <li>– <a href="#View-dollar">$ (jQuery or Zepto)</a></li>
262 <li>– <a href="#View-render">render</a></li>
263 <li>– <a href="#View-remove">remove</a></li>
264 <li>– <a href="#View-make">make</a></li>
265 <li>– <a href="#View-delegateEvents">delegateEvents</a></li>
266 </ul>
267
268 <a class="toc_title" href="#examples">
269 Examples
270 </a>
271
272 <a class="toc_title" href="#faq">
273 F.A.Q.
274 </a>
275 <ul class="toc_section">
276 <li>– <a href="#FAQ-events">Catalog of Events</a></li>
277 <li>– <a href="#FAQ-nested">Nested Models & Collections</a></li>
278 <li>– <a href="#FAQ-bootstrap">Loading Bootstrapped Models</a></li>
279 <li>– <a href="#FAQ-mvc">Traditional MVC</a></li>
280 <li>– <a href="#FAQ-this">Binding "this"</a></li>
281 <li>- <a href="#FAQ-rias">Other RIA Frameworks</a></li>
282 </ul>
283
284 <a class="toc_title" href="#changelog">
285 Change Log
286 </a>
287
288 </div>
289
290 <div class="container">
291
292 <p>
293 <img style="width: 385px; height: 126px;" src="docs/images/backbone.png" alt="Backbone.js" />
294 </p>
295
296 <p>
297 <a href="http://github.com/documentcloud/backbone/">Backbone</a>
298 supplies structure to JavaScript-heavy applications by providing <b>models</b> with
299 key-value binding and custom events, <b>collections</b> with a rich API of enumerable functions,
300 <b>views</b> with declarative event handling, and connects it all to your
301 existing application over a RESTful JSON interface.
302 </p>
303
304 <p>
305 The project is <a href="http://github.com/documentcloud/backbone/">hosted on GitHub</a>,
306 and the <a href="docs/backbone.html">annotated source code</a> is available,
307 as well as an online <a href="test/test.html">test suite</a>, and
308 <a href="examples/todos/index.html">example application</a>.
309 </p>
310
311 <p>
312 You can report bugs and discuss features on the
313 <a href="http://github.com/documentcloud/backbone/issues">issues page</a>,
314 on Freenode in the <tt>#documentcloud</tt> channel,
315 or send tweets to <a href="http://twitter.com/documentcloud">@documentcloud</a>.
316 </p>
317
318 <p>
319 <i>
320 Backbone is an open-source component of
321 <a href="http://documentcloud.org/">DocumentCloud</a>.
322 </i>
323 </p>
324
325 <h2 id="downloads">
326 Downloads & Dependencies
327 <span style="padding-left: 7px; font-size:11px; font-weight: normal;" class="interface">(Right-click, and use "Save As")</span>
328 </h2>
329
330 <table>
331 <tr>
332 <td><a href="backbone.js">Development Version (0.3.3)</a></td>
333 <td><i>35kb, Uncompressed with Comments</i></td>
334 </tr>
335 <tr>
336 <td><a href="backbone-min.js">Production Version (0.3.3)</a></td>
337 <td><i>3.9kb, Packed and Gzipped</i></td>
338 </tr>
339 </table>
340
341 <p>
342 Backbone's only hard dependency is
343 <a href="http://documentcloud.github.com/underscore/">Underscore.js</a>.
344 For RESTful persistence, and DOM manipulation with
345 <a href="#View">Backbone.View</a>,
346 it's highly recommended to include
347 <a href="https://github.com/douglascrockford/JSON-js">json2.js</a>, and either
348 <a href="http://jquery.com">jQuery</a> or <a href="http://zeptojs.com/">Zepto</a>.
349 </p>
350
351 <h2 id="Introduction">Introduction</h2>
352
353 <p>
354 When working on a web application that involves a lot of JavaScript, one
355 of the first things you learn is to stop tying your data to the DOM. It's all
356 too easy to create JavaScript applications that end up as tangled piles of
357 jQuery selectors and callbacks, all trying frantically to keep data in
358 sync between the HTML UI, your JavaScript logic, and the database on your
359 server. For rich client-side applications, a more structured approach
360 is helpful.
361 </p>
362
363 <p>
364 With Backbone, you represent your data as
365 <a href="#Model">Models</a>, which can be created, validated, destroyed,
366 and saved to the server. Whenever a UI action causes an attribute of
367 a model to change, the model triggers a <i>"change"</i> event; all
368 the <a href="#View">Views</a> that display the model's data are notified of the
369 event, causing them to re-render. You don't have to write the glue
370 code that looks into the DOM to find an element with a specific <i>id</i>,
371 and update the HTML manually
372 — when the model changes, the views simply update themselves.
373 </p>
374
375 <p>
376 Many of the examples that follow are runnable. Click the <i>play</i> button
377 to execute them.
378 </p>
379
380 <h2 id="Events">Backbone.Events</h2>
381
382 <p>
383 <b>Events</b> is a module that can be mixed in to any object, giving the
384 object the ability to bind and trigger custom named events. Events do not
385 have to be declared before they are bound, and may take passed arguments.
386 For example:
387 </p>
388
389<pre class="runnable">
390var object = {};
391
392_.extend(object, Backbone.Events);
393
394object.bind("alert", function(msg) {
395 alert("Triggered " + msg);
396});
397
398object.trigger("alert", "an event");
399</pre>
400
401 <p id="Events-bind">
402 <b class="header">bind</b><code>object.bind(event, callback)</code>
403 <br />
404 Bind a <b>callback</b> function to an object. The callback will be invoked
405 whenever the <b>event</b> (specified by an arbitrary string identifier) is fired.
406 If you have a large number of different events on a page, the convention is to use colons to
407 namespace them: <tt>"poll:start"</tt>, or <tt>"change:selection"</tt>
408 </p>
409
410 <p>
411 Callbacks bound to the special
412 <tt>"all"</tt> event will be triggered when any event occurs, and are passed
413 the name of the event as the first argument. For example, to proxy all events
414 from one object to another:
415 </p>
416
417<pre>
418proxy.bind("all", function(eventName) {
419 object.trigger(eventName);
420});
421</pre>
422
423 <p id="Events-unbind">
424 <b class="header">unbind</b><code>object.unbind([event], [callback])</code>
425 <br />
426 Remove a previously-bound <b>callback</b> function from an object. If no
427 callback is specified, all callbacks for the <b>event</b> will be
428 removed. If no event is specified, <i>all</i> event callbacks on the object
429 will be removed.
430 </p>
431
432<pre>
433object.unbind("change", onChange); // Removes just the onChange callback.
434
435object.unbind("change"); // Removes all "change" callbacks.
436
437object.unbind(); // Removes all callbacks on object.
438</pre>
439
440 <p id="Events-trigger">
441 <b class="header">trigger</b><code>object.trigger(event, [*args])</code>
442 <br />
443 Trigger callbacks for the given <b>event</b>. Subsequent arguments to
444 <b>trigger</b> will be passed along to the event callbacks.
445 </p>
446
447 <h2 id="Model">Backbone.Model</h2>
448
449 <p>
450 <b>Models</b> are the heart of any JavaScript application, containing
451 the interactive data as well as a large part of the logic surrounding it:
452 conversions, validations, computed properties, and access control. You
453 extend <b>Backbone.Model</b> with your domain-specific methods, and
454 <b>Model</b> provides a basic set of functionality for managing changes.
455 </p>
456
457 <p>
458 The following is a contrived example, but it demonstrates defining a model
459 with a custom method, setting an attribute, and firing an event keyed
460 to changes in that specific attribute.
461 After running this code once, <tt>sidebar</tt> will be
462 available in your browser's console, so you can play around with it.
463 </p>
464
465<pre class="runnable">
466var Sidebar = Backbone.Model.extend({
467 promptColor: function() {
468 var cssColor = prompt("Please enter a CSS color:");
469 this.set({color: cssColor});
470 }
471});
472
473window.sidebar = new Sidebar;
474
475sidebar.bind('change:color', function(model, color) {
476 $('#sidebar').css({background: color});
477});
478
479sidebar.set({color: 'white'});
480
481sidebar.promptColor();
482</pre>
483
484 <p id="Model-extend">
485 <b class="header">extend</b><code>Backbone.Model.extend(properties, [classProperties])</code>
486 <br />
487 To create a <b>Model</b> class of your own, you extend <b>Backbone.Model</b>
488 and provide instance <b>properties</b>, as well as optional
489 <b>classProperties</b> to be attached directly to the constructor function.
490 </p>
491
492 <p>
493 <b>extend</b> correctly sets up the prototype chain, so subclasses created
494 with <b>extend</b> can be further extended and subclassed as far as you like.
495 </p>
496
497<pre>
498var Note = Backbone.Model.extend({
499
500 initialize: function() { ... },
501
502 author: function() { ... },
503
504 coordinates: function() { ... },
505
506 allowedToEdit: function(account) {
507 return true;
508 }
509
510});
511
512var PrivateNote = Note.extend({
513
514 allowedToEdit: function(account) {
515 return account.owns(this);
516 }
517
518});
519</pre>
520
521 <p class="warning">
522 Brief aside on <tt>super</tt>: JavaScript does not provide
523 a simple way to call super — the function of the same name defined
524 higher on the prototype chain. If you override a core function like
525 <tt>set</tt>, or <tt>save</tt>, and you want to invoke the
526 parent object's implementation, you'll have to explicitly call it, along these lines:
527 </p>
528
529<pre>
530var Note = Backbone.Model.extend({
531 set: function(attributes, options) {
532 Backbone.Model.prototype.set.call(this, attributes, options);
533 ...
534 }
535});
536</pre>
537
538 <p id="Model-constructor">
539 <b class="header">constructor / initialize</b><code>new Model([attributes])</code>
540 <br />
541 When creating an instance of a model, you can pass in the initial values
542 of the <b>attributes</b>, which will be <a href="#Model-set">set</a> on the
543 model. If you define an <b>initialize</b> function, it will be invoked when
544 the model is created.
545 </p>
546
547<pre>
548new Book({
549 title: "One Thousand and One Nights",
550 author: "Scheherazade"
551});
552</pre>
553
554 <p id="Model-get">
555 <b class="header">get</b><code>model.get(attribute)</code>
556 <br />
557 Get the current value of an attribute from the model. For example:
558 <tt>note.get("title")</tt>
559 </p>
560
561 <p id="Model-escape">
562 <b class="header">escape</b><code>model.escape(attribute)</code>
563 <br />
564 Similar to <a href="#Model-get">get</a>, but returns the HTML-escaped version
565 of a model's attribute. If you're interpolating data from the model into
566 HTML, using <b>escape</b> to retrieve attributes will prevent
567 <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> attacks.
568 </p>
569
570<pre class="runnable">
571var hacker = new Backbone.Model({
572 name: "<script>alert('xss')</script>"
573});
574
575alert(hacker.escape('name'));
576</pre>
577
578 <p id="Model-set">
579 <b class="header">set</b><code>model.set(attributes, [options])</code>
580 <br />
581 Set a hash of attributes (one or many) on the model. If any of the attributes
582 change the models state, a <tt>"change"</tt> event will be triggered, unless
583 <tt>{silent: true}</tt> is passed as an option. Change events for specific
584 attributes are also triggered, and you can bind to those as well, for example:
585 <tt>change:title</tt>, and <tt>change:content</tt>.
586 </p>
587
588<pre>
589note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
590</pre>
591
592 <p>
593 If the model has a <a href="#Model-validate">validate</a> method,
594 it will be validated before the attributes are set, no changes will
595 occur if the validation fails, and <b>set</b> will return <tt>false</tt>.
596 You may also pass an <tt>error</tt>
597 callback in the options, which will be invoked instead of triggering an
598 <tt>"error"</tt> event, should validation fail.
599 </p>
600
601 <p id="Model-escape">
602 <b class="header">escape</b><code>model.escape(attribute)</code>
603 <br />
604 Similar to <a href="#Model-get">get</a>, but returns the HTML-escaped version
605 of a model's attribute. If you're interpolating data from the model into
606 HTML, using <b>escape</b> to retrieve attributes will prevent
607 <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> attacks.
608 </p>
609
610<pre class="runnable">
611var hacker = new Backbone.Model({
612 name: "<script>alert('xss')</script>"
613});
614
615alert(hacker.escape('name'));
616</pre>
617
618 <p id="Model-has">
619 <b class="header">has</b><code>model.has(attribute)</code>
620 <br />
621 Returns <tt>true</tt> if the attribute is set to a non-null or non-undefined
622 value.
623 </p>
624
625<pre>
626if (note.has("title")) {
627 ...
628}
629</pre>
630
631 <p id="Model-unset">
632 <b class="header">unset</b><code>model.unset(attribute, [options])</code>
633 <br />
634 Remove an attribute by deleting it from the internal attributes hash.
635 Fires a <tt>"change"</tt> event unless <tt>silent</tt> is passed as an option.
636 </p>
637
638 <p id="Model-clear">
639 <b class="header">clear</b><code>model.clear([options])</code>
640 <br />
641 Removes all attributes from the model. Fires a <tt>"change"</tt> event unless
642 <tt>silent</tt> is passed as an option.
643 </p>
644
645 <p id="Model-id">
646 <b class="header">id</b><code>model.id</code>
647 <br />
648 A special property of models, the <b>id</b> is an arbitrary string
649 (integer id or UUID). If you set the <b>id</b> in the
650 attributes hash, it will be copied onto the model as a direct property.
651 Models can be retrieved by id from collections, and the id is used to generate
652 model URLs by default.
653 </p>
654
655 <p id="Model-cid">
656 <b class="header">cid</b><code>model.cid</code>
657 <br />
658 A special property of models, the <b>cid</b> or client id is a unique identifier
659 automatically assigned to all models when they're first created. Client ids
660 are handy when the model has not yet been saved to the server, and does not
661 yet have its eventual true <b>id</b>, but already needs to be visible in the UI.
662 Client ids take the form: <tt>c1, c2, c3 ...</tt>
663 </p>
664
665 <p id="Model-attributes">
666 <b class="header">attributes</b><code>model.attributes</code>
667 <br />
668 The <b>attributes</b> property is the internal hash containing the model's
669 state. Please use <a href="#Model-set">set</a> to update the attributes instead of modifying
670 them directly. If you'd like to retrieve and munge a copy of the model's
671 attributes, use <a href="#Model-toJSON">toJSON</a> instead.
672 </p>
673
674 <p id="Model-defaults">
675 <b class="header">defaults</b><code>model.defaults or model.defaults()</code>
676 <br />
677 The <b>defaults</b> hash (or function) can be used to specify the default
678 attributes for your model. When creating an instance of the model,
679 any unspecified attributes will be set to their default value.
680 </p>
681
682<pre class="runnable">
683var Meal = Backbone.Model.extend({
684 defaults: {
685 "appetizer": "caesar salad",
686 "entree": "ravioli",
687 "dessert": "cheesecake"
688 }
689});
690
691alert("Dessert will be " + (new Meal).get('dessert'));
692</pre>
693
694 <p id="Model-toJSON">
695 <b class="header">toJSON</b><code>model.toJSON()</code>
696 <br />
697 Return a copy of the model's <a href="#Model-attributes">attributes</a> for JSON stringification.
698 This can be used for persistence, serialization, or for augmentation before
699 being handed off to a view. The name of this method is a bit confusing, as
700 it doesn't actually return a JSON string — but I'm afraid that it's
701 the way that the <a href="https://developer.mozilla.org/en/JSON#toJSON()_method">JavaScript API for <b>JSON.stringify</b> works</a>.
702 </p>
703
704<pre class="runnable">
705var artist = new Backbone.Model({
706 firstName: "Wassily",
707 lastName: "Kandinsky"
708});
709
710artist.set({birthday: "December 16, 1866"});
711
712alert(JSON.stringify(artist));
713</pre>
714
715 <p id="Model-fetch">
716 <b class="header">fetch</b><code>model.fetch([options])</code>
717 <br />
718 Refreshes the model's state from the server. Useful if the model has never
719 been populated with data, or if you'd like to ensure that you have the
720 latest server state. A <tt>"change"</tt> event will be triggered if the
721 server's state differs from the current attributes. Accepts
722 <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which
723 are passed <tt>(model, response)</tt> as arguments.
724 </p>
725
726<pre>
727// Poll every 10 seconds to keep the channel model up-to-date.
728setInterval(function() {
729 channel.fetch();
730}, 10000);
731</pre>
732
733 <p id="Model-save">
734 <b class="header">save</b><code>model.save([attributes], [options])</code>
735 <br />
736 Save a model to your database (or alternative persistence layer),
737 by delegating to <a href="#Sync">Backbone.sync</a>. The <b>attributes</b>
738 hash (as in <a href="#Model-set">set</a>) should contain the attributes
739 you'd like to change -- keys that aren't mentioned won't be altered.
740 If the model has a <a href="#Model-validate">validate</a>
741 method, and validation fails, the model will not be saved. If the model
742 <a href="#Model-isNew">isNew</a>, the save will be a <tt>"create"</tt>
743 (HTTP <tt>POST</tt>), if the model already
744 exists on the server, the save will be an <tt>"update"</tt> (HTTP <tt>PUT</tt>).
745 </p>
746
747 <p>
748 In the following example, notice how because the model has never been
749 saved previously, our overridden version of <tt>Backbone.sync</tt> receives a <tt>"create"</tt> request.
750 </p>
751
752<pre class="runnable">
753Backbone.sync = function(method, model) {
754 alert(method + ": " + JSON.stringify(model));
755};
756
757var book = new Backbone.Model({
758 title: "The Rough Riders",
759 author: "Theodore Roosevelt"
760});
761
762book.save();
763</pre>
764
765 <p>
766 <b>save</b> accepts <tt>success</tt> and <tt>error</tt> callbacks in the
767 options hash, which are passed <tt>(model, response)</tt> as arguments.
768 The <tt>error</tt> callback will also be invoked if the model has a
769 <tt>validate</tt> method, and validation fails. If a server-side
770 validation fails, return a non-<tt>200</tt> HTTP response code, along with
771 an error response in text or JSON.
772 </p>
773
774<pre>
775book.save({author: "F.D.R."}, {error: function(){ ... }});
776</pre>
777
778 <p id="Model-destroy">
779 <b class="header">destroy</b><code>model.destroy([options])</code>
780 <br />
781 Destroys the model on the server by delegating an HTTP <tt>DELETE</tt>
782 request to <a href="#Sync">Backbone.sync</a>. Accepts
783 <tt>success</tt> and <tt>error</tt> callbacks in the options hash.
784 Triggers a <tt>"destroy"</tt> event on the model, which will bubble up
785 through any collections that contain it.
786 </p>
787
788<pre>
789book.destroy({success: function(model, response) {
790 ...
791}});
792</pre>
793
794 <p id="Model-validate">
795 <b class="header">validate</b><code>model.validate(attributes)</code>
796 <br />
797 This method is left undefined, and you're encouraged to override it with
798 your custom validation logic, if you have any that can be performed
799 in JavaScript. <b>validate</b> is called before <tt>set</tt> and
800 <tt>save</tt>, and is passed the attributes that are about to be updated.
801 If the model and attributes are valid, don't return anything from <b>validate</b>;
802 if the attributes are invalid, return an error of your choosing. It
803 can be as simple as a string error message to be displayed, or a complete
804 error object that describes the error programmatically. <tt>set</tt> and
805 <tt>save</tt> will not continue if <b>validate</b> returns an error.
806 Failed validations trigger an <tt>"error"</tt> event.
807 </p>
808
809<pre class="runnable">
810var Chapter = Backbone.Model.extend({
811 validate: function(attrs) {
812 if (attrs.end < attrs.start) {
813 return "can't end before it starts";
814 }
815 }
816});
817
818var one = new Chapter({
819 title : "Chapter One: The Beginning"
820});
821
822one.bind("error", function(model, error) {
823 alert(model.get("title") + " " + error);
824});
825
826one.set({
827 start: 15,
828 end: 10
829});
830</pre>
831
832 <p>
833 <tt>"error"</tt> events are useful for providing coarse-grained error
834 messages at the model or collection level, but if you have a specific view
835 that can better handle the error, you may override and suppress the event
836 by passing an <tt>error</tt> callback directly:
837 </p>
838
839<pre>
840account.set({access: "unlimited"}, {
841 error: function(model, error) {
842 alert(error);
843 }
844});
845</pre>
846
847 <p id="Model-url">
848 <b class="header">url</b><code>model.url()</code>
849 <br />
850 Returns the relative URL where the model's resource would be located on
851 the server. If your models are located somewhere else, override this method
852 with the correct logic. Generates URLs of the form: <tt>"/[collection.url]/[id]"</tt>,
853 falling back to <tt>"/[urlRoot]/id"</tt> if the model is not part of a collection.
854 </p>
855
856 <p>
857 Delegates to <a href="#Collection-url">Collection#url</a> to generate the
858 URL, so make sure that you have it defined, or a <a href="#Model-urlRoot">urlRoot</a>
859 property, if all models of this class share a common root URL.
860 A model with an id of <tt>101</tt>, stored in a
861 <a href="#Collection">Backbone.Collection</a> with a <tt>url</tt> of <tt>"/documents/7/notes"</tt>,
862 would have this URL: <tt>"/documents/7/notes/101"</tt>
863 </p>
864
865 <p id="Model-urlRoot">
866 <b class="header">urlRoot</b><code>model.urlRoot</code>
867 <br />
868 Specify a <tt>urlRoot</tt> if you're using a model outside of a collection,
869 to enable the default <a href="#Model-url">url</a> function to generate
870 URLs based on the model id. <tt>"/[urlRoot]/id"</tt>
871 </p>
872
873<pre class="runnable">
874var Book = Backbone.Model.extend({urlRoot : '/books'});
875
876var solaris = new Book({id: "1083-lem-solaris"});
877
878alert(solaris.url());
879</pre>
880
881 <p id="Model-parse">
882 <b class="header">parse</b><code>model.parse(response)</code>
883 <br />
884 <b>parse</b> is called whenever a model's data is returned by the
885 server, in <a href="#Model-fetch">fetch</a>, and <a href="#Model-save">save</a>.
886 The function is passed the raw <tt>response</tt> object, and should return
887 the attributes hash to be <a href="#Model-set">set</a> on the model. The
888 default implementation is a no-op, simply passing through the JSON response.
889 Override this if you need to work with a preexisting API, or better namespace
890 your responses.
891 </p>
892
893 <p>
894 If you're working with a Rails backend, you'll notice that Rails' default
895 <tt>to_json</tt> implementation includes a model's attributes under a
896 namespace. To disable this behavior for seamless Backbone integration, set:
897 </p>
898
899<pre>
900ActiveRecord::Base.include_root_in_json = false
901</pre>
902
903 <p id="Model-clone">
904 <b class="header">clone</b><code>model.clone()</code>
905 <br />
906 Returns a new instance of the model with identical attributes.
907 </p>
908
909 <p id="Model-isNew">
910 <b class="header">isNew</b><code>model.isNew()</code>
911 <br />
912 Has this model been saved to the server yet? If the model does not yet have
913 an <tt>id</tt>, it is considered to be new.
914 </p>
915
916 <p id="Model-change">
917 <b class="header">change</b><code>model.change()</code>
918 <br />
919 Manually trigger the <tt>"change"</tt> event.
920 If you've been passing <tt>{silent: true}</tt> to the <a href="#Model-set">set</a> function in order to
921 aggregate rapid changes to a model, you'll want to call <tt>model.change()</tt>
922 when you're all finished.
923 </p>
924
925 <p id="Model-hasChanged">
926 <b class="header">hasChanged</b><code>model.hasChanged([attribute])</code>
927 <br />
928 Has the model changed since the last <tt>"change"</tt> event? If an <b>attribute</b>
929 is passed, returns <tt>true</tt> if that specific attribute has changed.
930 </p>
931
932<pre>
933book.bind("change", function() {
934 if (book.hasChanged("title")) {
935 ...
936 }
937});
938</pre>
939
940 <p id="Model-changedAttributes">
941 <b class="header">changedAttributes</b><code>model.changedAttributes([attributes])</code>
942 <br />
943 Retrieve a hash of only the model's attributes that have changed. Optionally,
944 an external <b>attributes</b> hash can be passed in, returning
945 the attributes in that hash which differ from the model. This can be used
946 to figure out which portions of a view should be updated, or what calls
947 need to be made to sync the changes to the server.
948 </p>
949
950 <p id="Model-previous">
951 <b class="header">previous</b><code>model.previous(attribute)</code>
952 <br />
953 During a <tt>"change"</tt> event, this method can be used to get the
954 previous value of a changed attribute.
955 </p>
956
957<pre class="runnable">
958var bill = new Backbone.Model({
959 name: "Bill Smith"
960});
961
962bill.bind("change:name", function(model, name) {
963 alert("Changed name from " + bill.previous("name") + " to " + name);
964});
965
966bill.set({name : "Bill Jones"});
967</pre>
968
969 <p id="Model-previousAttributes">
970 <b class="header">previousAttributes</b><code>model.previousAttributes()</code>
971 <br />
972 Return a copy of the model's previous attributes. Useful for getting a
973 diff between versions of a model, or getting back to a valid state after
974 an error occurs.
975 </p>
976
977 <h2 id="Collection">Backbone.Collection</h2>
978
979 <p>
980 Collections are ordered sets of models. You can to bind <tt>"change"</tt> events
981 to be notified when any model in the collection has been modified,
982 listen for <tt>"add"</tt> and <tt>"remove"</tt> events, <tt>fetch</tt>
983 the collection from the server, and use a full suite of
984 <a href="#Collection-Underscore-Methods">Underscore.js methods</a>.
985 </p>
986
987 <p>
988 Any event that is triggered on a model in a collection will also be
989 triggered on the collection directly, for convenience.
990 This allows you to listen for changes to specific attributes in any
991 model in a collection, for example:
992 <tt>Documents.bind("change:selected", ...)</tt>
993 </p>
994
995 <p id="Collection-extend">
996 <b class="header">extend</b><code>Backbone.Collection.extend(properties, [classProperties])</code>
997 <br />
998 To create a <b>Collection</b> class of your own, extend <b>Backbone.Collection</b>,
999 providing instance <b>properties</b>, as well as optional <b>classProperties</b> to be attached
1000 directly to the collection's constructor function.
1001 </p>
1002
1003 <p id="Collection-model">
1004 <b class="header">model</b><code>collection.model</code>
1005 <br />
1006 Override this property to specify the model class that the collection
1007 contains. If defined, you can pass raw attributes objects (and arrays) to
1008 <a href="#Collection-add">add</a>, <a href="#Collection-create">create</a>,
1009 and <a href="#Collection-refresh">refresh</a>, and the attributes will be
1010 converted into a model of the proper type.
1011 </p>
1012
1013<pre>
1014var Library = Backbone.Collection.extend({
1015 model: Book
1016});
1017</pre>
1018
1019 <p id="Collection-constructor">
1020 <b class="header">constructor / initialize</b><code>new Collection([models], [options])</code>
1021 <br />
1022 When creating a Collection, you may choose to pass in the initial array of <b>models</b>.
1023 The collection's <a href="#Collection-comparator">comparator</a> function
1024 may be included as an option. If you define an <b>initialize</b> function, it will be
1025 invoked when the collection is created.
1026 </p>
1027
1028<pre>
1029var tabs = new TabSet([tab1, tab2, tab3]);
1030</pre>
1031
1032 <p id="Collection-models">
1033 <b class="header">models</b><code>collection.models</code>
1034 <br />
1035 Raw access to the JavaScript array of models inside of the collection. Usually you'll
1036 want to use <tt>get</tt>, <tt>at</tt>, or the <b>Underscore methods</b>
1037 to access model objects, but occasionally a direct reference to the array
1038 is desired.
1039 </p>
1040
1041 <p id="Collection-toJSON">
1042 <b class="header">toJSON</b><code>collection.toJSON()</code>
1043 <br />
1044 Return an array containing the attributes hash of each model in the
1045 collection. This can be used to serialize and persist the
1046 collection as a whole. The name of this method is a bit confusing, because
1047 it conforms to
1048 <a href="https://developer.mozilla.org/en/JSON#toJSON()_method">JavaScript's JSON API</a>.
1049 </p>
1050
1051<pre class="runnable">
1052var collection = new Backbone.Collection([
1053 {name: "Tim", age: 5},
1054 {name: "Ida", age: 26},
1055 {name: "Rob", age: 55}
1056]);
1057
1058alert(JSON.stringify(collection));
1059</pre>
1060
1061 <p id="Collection-Underscore-Methods">
1062 <b class="header">Underscore Methods (25)</b>
1063 <br />
1064 Backbone proxies to <b>Underscore.js</b> to provide 25 iteration functions
1065 on <b>Backbone.Collection</b>. They aren't all documented here, but
1066 you can take a look at the Underscore documentation for the full details…
1067 </p>
1068
1069 <ul>
1070 <li><a href="http://documentcloud.github.com/underscore/#each">forEach (each)</a></li>
1071 <li><a href="http://documentcloud.github.com/underscore/#map">map</a></li>
1072 <li><a href="http://documentcloud.github.com/underscore/#reduce">reduce (foldl, inject)</a></li>
1073 <li><a href="http://documentcloud.github.com/underscore/#reduceRight">reduceRight (foldr)</a></li>
1074 <li><a href="http://documentcloud.github.com/underscore/#detect">find (detect)</a></li>
1075 <li><a href="http://documentcloud.github.com/underscore/#select">filter (select)</a></li>
1076 <li><a href="http://documentcloud.github.com/underscore/#reject">reject</a></li>
1077 <li><a href="http://documentcloud.github.com/underscore/#all">every (all)</a></li>
1078 <li><a href="http://documentcloud.github.com/underscore/#any">some (any)</a></li>
1079 <li><a href="http://documentcloud.github.com/underscore/#include">include</a></li>
1080 <li><a href="http://documentcloud.github.com/underscore/#invoke">invoke</a></li>
1081 <li><a href="http://documentcloud.github.com/underscore/#max">max</a></li>
1082 <li><a href="http://documentcloud.github.com/underscore/#min">min</a></li>
1083 <li><a href="http://documentcloud.github.com/underscore/#sortBy">sortBy</a></li>
1084 <li><a href="http://documentcloud.github.com/underscore/#sortedIndex">sortedIndex</a></li>
1085 <li><a href="http://documentcloud.github.com/underscore/#toArray">toArray</a></li>
1086 <li><a href="http://documentcloud.github.com/underscore/#size">size</a></li>
1087 <li><a href="http://documentcloud.github.com/underscore/#first">first</a></li>
1088 <li><a href="http://documentcloud.github.com/underscore/#rest">rest</a></li>
1089 <li><a href="http://documentcloud.github.com/underscore/#last">last</a></li>
1090 <li><a href="http://documentcloud.github.com/underscore/#without">without</a></li>
1091 <li><a href="http://documentcloud.github.com/underscore/#indexOf">indexOf</a></li>
1092 <li><a href="http://documentcloud.github.com/underscore/#lastIndexOf">lastIndexOf</a></li>
1093 <li><a href="http://documentcloud.github.com/underscore/#isEmpty">isEmpty</a></li>
1094 <li><a href="http://documentcloud.github.com/underscore/#chain">chain</a></li>
1095 </ul>
1096
1097<pre>
1098Books.each(function(book) {
1099 book.publish();
1100});
1101
1102var titles = Books.map(function(book) {
1103 return book.get("title");
1104});
1105
1106var publishedBooks = Books.filter(function(book) {
1107 return book.get("published") === true;
1108});
1109
1110var alphabetical = Books.sortBy(function(book) {
1111 return book.author.get("name").toLowerCase();
1112});
1113</pre>
1114
1115 <p id="Collection-add">
1116 <b class="header">add</b><code>collection.add(models, [options])</code>
1117 <br />
1118 Add a model (or an array of models) to the collection. Fires an <tt>"add"</tt>
1119 event, which you can pass <tt>{silent: true}</tt> to suppress. If a
1120 <a href="#Collection-model">model</a> property is defined, you may also pass
1121 raw attributes objects, and have them be vivified as instances of the model.
1122 </p>
1123
1124<pre class="runnable">
1125var ships = new Backbone.Collection;
1126
1127ships.bind("add", function(ship) {
1128 alert("Ahoy " + ship.get("name") + "!");
1129});
1130
1131ships.add([
1132 {name: "Flying Dutchman"},
1133 {name: "Black Pearl"}
1134]);
1135</pre>
1136
1137 <p id="Collection-remove">
1138 <b class="header">remove</b><code>collection.remove(models, [options])</code>
1139 <br />
1140 Remove a model (or an array of models) from the collection. Fires a
1141 <tt>"remove"</tt> event, which you can use <tt>silent</tt>
1142 to suppress.
1143 </p>
1144
1145 <p id="Collection-get">
1146 <b class="header">get</b><code>collection.get(id)</code>
1147 <br />
1148 Get a model from a collection, specified by <b>id</b>.
1149 </p>
1150
1151<pre>
1152var book = Library.get(110);
1153</pre>
1154
1155 <p id="Collection-getByCid">
1156 <b class="header">getByCid</b><code>collection.getByCid(cid)</code>
1157 <br />
1158 Get a model from a collection, specified by client id. The client id
1159 is the <tt>.cid</tt> property of the model, automatically assigned whenever
1160 a model is created. Useful for models which have not yet been saved to
1161 the server, and do not yet have true ids.
1162 </p>
1163
1164 <p id="Collection-at">
1165 <b class="header">at</b><code>collection.at(index)</code>
1166 <br />
1167 Get a model from a collection, specified by index. Useful if your collection
1168 is sorted, and if your collection isn't sorted, <b>at</b> will still
1169 retrieve models in insertion order.
1170 </p>
1171
1172 <p id="Collection-length">
1173 <b class="header">length</b><code>collection.length</code>
1174 <br />
1175 Like an array, a Collection maintains a <tt>length</tt> property, counting
1176 the number of models it contains.
1177 </p>
1178
1179 <p id="Collection-comparator">
1180 <b class="header">comparator</b><code>collection.comparator</code>
1181 <br />
1182 By default there is no <b>comparator</b> function on a collection.
1183 If you define a comparator, it will be used to maintain
1184 the collection in sorted order. This means that as models are added,
1185 they are inserted at the correct index in <tt>collection.models</tt>.
1186 Comparator functions take a model and return a numeric or string value
1187 by which the model should be ordered relative to others.
1188 </p>
1189
1190 <p>
1191 Note how even though all of the chapters in this example are added backwards,
1192 they come out in the proper order:
1193 </p>
1194
1195<pre class="runnable">
1196var Chapter = Backbone.Model;
1197var chapters = new Backbone.Collection;
1198
1199chapters.comparator = function(chapter) {
1200 return chapter.get("page");
1201};
1202
1203chapters.add(new Chapter({page: 9, title: "The End"}));
1204chapters.add(new Chapter({page: 5, title: "The Middle"}));
1205chapters.add(new Chapter({page: 1, title: "The Beginning"}));
1206
1207alert(chapters.pluck('title'));
1208</pre>
1209
1210 <p class="warning">
1211 Brief aside: This comparator function is different than JavaScript's regular
1212 "sort", which must return <tt>0</tt>, <tt>1</tt>, or <tt>-1</tt>,
1213 and is more similar to a <tt>sortBy</tt> — a much nicer API.
1214 </p>
1215
1216 <p id="Collection-sort">
1217 <b class="header">sort</b><code>collection.sort([options])</code>
1218 <br />
1219 Force a collection to re-sort itself. You don't need to call this under
1220 normal circumstances, as a collection with a <a href="#Collection-comparator">comparator</a> function
1221 will maintain itself in proper sort order at all times. Calling <b>sort</b>
1222 triggers the collection's <tt>"refresh"</tt> event, unless silenced by passing
1223 <tt>{silent: true}</tt>
1224 </p>
1225
1226 <p id="Collection-pluck">
1227 <b class="header">pluck</b><code>collection.pluck(attribute)</code>
1228 <br />
1229 Pluck an attribute from each model in the collection. Equivalent to calling
1230 <tt>map</tt>, and returning a single attribute from the iterator.
1231 </p>
1232
1233<pre class="runnable">
1234var stooges = new Backbone.Collection([
1235 new Backbone.Model({name: "Curly"}),
1236 new Backbone.Model({name: "Larry"}),
1237 new Backbone.Model({name: "Moe"})
1238]);
1239
1240var names = stooges.pluck("name");
1241
1242alert(JSON.stringify(names));
1243</pre>
1244
1245 <p id="Collection-url">
1246 <b class="header">url</b><code>collection.url or collection.url()</code>
1247 <br />
1248 Set the <b>url</b> property (or function) on a collection to reference
1249 its location on the server. Models within the collection will use <b>url</b>
1250 to construct URLs of their own.
1251 </p>
1252
1253<pre>
1254var Notes = Backbone.Collection.extend({
1255 url: '/notes'
1256});
1257
1258// Or, something more sophisticated:
1259
1260var Notes = Backbone.Collection.extend({
1261 url: function() {
1262 return this.document.url() + '/notes';
1263 }
1264});
1265</pre>
1266
1267 <p id="Collection-parse">
1268 <b class="header">parse</b><code>collection.parse(response)</code>
1269 <br />
1270 <b>parse</b> is called by Backbone whenever a collection's models are
1271 returned by the server, in <a href="#Collection-fetch">fetch</a>.
1272 The function is passed the raw <tt>response</tt> object, and should return
1273 the array of model attributes to be <a href="#Collection-add">added</a>
1274 to the collection. The default implementation is a no-op, simply passing
1275 through the JSON response. Override this if you need to work with a
1276 preexisting API, or better namespace your responses.
1277 </p>
1278
1279<pre>
1280var Tweets = Backbone.Collection.extend({
1281 // The Twitter Search API returns tweets under "results".
1282 parse: function(response) {
1283 return response.results;
1284 }
1285});
1286</pre>
1287
1288 <p id="Collection-fetch">
1289 <b class="header">fetch</b><code>collection.fetch([options])</code>
1290 <br />
1291 Fetch the default set of models for this collection from the server,
1292 refreshing the collection when they arrive. The <b>options</b> hash takes
1293 <tt>success</tt> and <tt>error</tt>
1294 callbacks which will be passed <tt>(collection, response)</tt> as arguments.
1295 When the model data returns from the server, the collection will
1296 <a href="#Collection-refresh">refresh</a>.
1297 Delegates to <a href="#Sync">Backbone.sync</a>
1298 under the covers, for custom persistence strategies.
1299 The server handler for <b>fetch</b> requests should return a JSON array of
1300 models.
1301 </p>
1302
1303<pre class="runnable">
1304Backbone.sync = function(method, model) {
1305 alert(method + ": " + model.url);
1306};
1307
1308var Accounts = new Backbone.Collection;
1309Accounts.url = '/accounts';
1310
1311Accounts.fetch();
1312</pre>
1313
1314 <p>
1315 If you'd like to add the incoming models to the current collection, instead
1316 of replacing the collection's contents, pass <tt>{add: true}</tt> as an
1317 option to <b>fetch</b>.
1318 </p>
1319
1320 <p>
1321 Note that <b>fetch</b> should not be used to populate collections on
1322 page load — all models needed at load time should already be
1323 <a href="#FAQ-bootstrap">bootstrapped</a> in to place. <b>fetch</b> is
1324 intended for lazily-loading models for interfaces that are not needed
1325 immediately: for example, documents with collections of notes that may be
1326 toggled open and closed.
1327 </p>
1328
1329 <p id="Collection-refresh">
1330 <b class="header">refresh</b><code>collection.refresh(models, [options])</code>
1331 <br />
1332 Adding and removing models one at a time is all well and good, but sometimes
1333 you have so many models to change that you'd rather just update the collection
1334 in bulk. Use <b>refresh</b> to replace a collection with a new list
1335 of models (or attribute hashes), triggering a single <tt>"refresh"</tt> event
1336 at the end. Pass <tt>{silent: true}</tt> to suppress the <tt>"refresh"</tt> event.
1337 </p>
1338
1339 <p>
1340 Here's an example using <b>refresh</b> to bootstrap a collection during initial page load,
1341 in a Rails application.
1342 </p>
1343
1344<pre>
1345<script>
1346 Accounts.refresh(<%= @accounts.to_json %>);
1347</script>
1348</pre>
1349
1350 <p id="Collection-create">
1351 <b class="header">create</b><code>collection.create(attributes, [options])</code>
1352 <br />
1353 Convenience to create a new instance of a model within a collection.
1354 Equivalent to instantiating a model with a hash of attributes,
1355 saving the model to the server, and adding the model to the set after being
1356 successfully created. Returns
1357 the model, or <tt>false</tt> if a validation error prevented the
1358 model from being created. In order for this to work, your should set the
1359 <a href="#Collection-model">model</a> property of the collection.
1360 </p>
1361
1362<pre>
1363var Library = Backbone.Collection.extend({
1364 model: Book
1365});
1366
1367var NYPL = new Library;
1368
1369var othello = NYPL.create({
1370 title: "Othello",
1371 author: "William Shakespeare"
1372});
1373</pre>
1374
1375 <h2 id="Controller">Backbone.Controller</h2>
1376
1377 <p>
1378 Web applications often choose to change their URL fragment (<tt>#fragment</tt>)
1379 in order to provide shareable, bookmarkable URLs for an Ajax-heavy application.
1380 <b>Backbone.Controller</b> provides methods for routing client-side URL
1381 fragments, and connecting them to actions and events.
1382 </p>
1383
1384 <p class="warning">
1385 Backbone controllers do not yet make use of HTML5 <b>pushState</b> and
1386 <b>replaceState</b>. Currently, <b>pushState</b> and <b>replaceState</b>
1387 need special handling on the server-side, cause you to mint duplicate URLs,
1388 and have an incomplete API. We may start supporting them in the future
1389 when these issues have been resolved.
1390 </p>
1391
1392 <p>
1393 During page load, after your application has finished creating all of its controllers,
1394 be sure to call <tt>Backbone.history.start()</tt> to route the initial URL.
1395 </p>
1396
1397 <p id="Controller-extend">
1398 <b class="header">extend</b><code>Backbone.Controller.extend(properties, [classProperties])</code>
1399 <br />
1400 Get started by creating a custom controller class. You'll
1401 want to define actions that are triggered when certain URL fragments are
1402 matched, and provide a <a href="#Controller-routes">routes</a> hash
1403 that pairs routes to actions.
1404 </p>
1405
1406<pre>
1407var Workspace = Backbone.Controller.extend({
1408
1409 routes: {
1410 "help": "help", // #help
1411 "search/:query": "search", // #search/kiwis
1412 "search/:query/p:page": "search" // #search/kiwis/p7
1413 },
1414
1415 help: function() {
1416 ...
1417 },
1418
1419 search: function(query, page) {
1420 ...
1421 }
1422
1423});
1424</pre>
1425
1426 <p id="Controller-routes">
1427 <b class="header">routes</b><code>controller.routes</code>
1428 <br />
1429 The routes hash maps URLs with parameters to functions on your controller,
1430 similar to the <a href="#View">View</a>'s <a href="#View-delegateEvents">events hash</a>.
1431 Routes can contain parameter parts, <tt>:param</tt>, which match a single URL
1432 component between slashes; and splat parts <tt>*splat</tt>, which can match
1433 any number of URL components.
1434 </p>
1435
1436 <p>
1437 For example, a route of <tt>"search/:query/p:page"</tt> will match
1438 a fragment of <tt>#search/obama/p2</tt>, passing <tt>"obama"</tt>
1439 and <tt>"2"</tt> to the action. A route of <tt>"file/*path"</tt> will
1440 match <tt>#file/nested/folder/file.txt</tt>,
1441 passing <tt>"nested/folder/file.txt"</tt> to the action.
1442 </p>
1443
1444 <p>
1445 When the visitor presses the back button, or enters a URL, and a particular
1446 route is matched, the name of the action will be fired as an
1447 <a href="#Events">event</a>, so that other objects can listen to the controller,
1448 and be notified. In the following example, visiting <tt>#help/uploading</tt>
1449 will fire a <tt>route:help</tt> event from the controller.
1450 </p>
1451
1452<pre>
1453routes: {
1454 "help/:page": "help",
1455 "download/*path": "download",
1456 "folder/:name": "openFolder",
1457 "folder/:name-:mode": "openFolder"
1458}
1459</pre>
1460
1461<pre>
1462controller.bind("route:help", function(page) {
1463 ...
1464});
1465</pre>
1466
1467 <p id="Controller-constructor">
1468 <b class="header">constructor / initialize</b><code>new Controller([options])</code>
1469 <br />
1470 When creating a new controller, you may pass its
1471 <a href="#Controller-routes">routes</a> hash directly as an option, if you
1472 choose. All <tt>options</tt> will also be passed to your <tt>initialize</tt>
1473 function, if defined.
1474 </p>
1475
1476 <p id="Controller-route">
1477 <b class="header">route</b><code>controller.route(route, name, callback)</code>
1478 <br />
1479 Manually create a route for the controller, The <tt>route</tt> argument may
1480 be a <a href="#Controller-routes">routing string</a> or regular expression.
1481 Each matching capture from the route or regular expression will be passed as
1482 an argument to the callback. The <tt>name</tt> argument will be triggered as
1483 a <tt>"route:name"</tt> event whenever the route is matched.
1484 </p>
1485
1486<pre>
1487initialize: function(options) {
1488
1489 // Matches #page/10, passing "10"
1490 this.route("page/:number", "page", function(number){ ... });
1491
1492 // Matches /117-a/b/c/open, passing "117-a/b/c"
1493 this.route(/^(.*?)\/open$/, "open", function(id){ ... });
1494
1495}
1496</pre>
1497
1498 <p id="Controller-saveLocation">
1499 <b class="header">saveLocation</b><code>controller.saveLocation(fragment)</code>
1500 <br />
1501 Whenever you reach a point in your application that you'd like to save
1502 as a URL, call <b>saveLocation</b> in order to update the URL fragment
1503 without triggering a <tt>hashchange</tt> event. (If you would prefer to
1504 trigger the event and routing, you can just set the hash directly.)
1505 </p>
1506
1507<pre>
1508openPage: function(pageNumber) {
1509 this.document.pages.at(pageNumber).open();
1510 this.saveLocation("page/" + pageNumber);
1511}
1512</pre>
1513
1514 <h2 id="History">Backbone.history</h2>
1515
1516 <p>
1517 <b>History</b> serves as a global router (per frame) to handle <tt>hashchange</tt>
1518 events, match the appropriate route, and trigger callbacks. You shouldn't
1519 ever have to create one of these yourself — you should use the reference
1520 to <tt>Backbone.history</tt> that will be created for you automatically if you make use
1521 of <a href="#Controller">Controllers</a> with <a href="#Controller-routes">routes</a>.
1522 </p>
1523
1524 <p id="History-start">
1525 <b class="header">start</b><code>Backbone.history.start()</code>
1526 <br />
1527 When all of your <a href="#Controller">Controllers</a> have been created,
1528 and all of the routes are set up properly, call <tt>Backbone.history.start()</tt>
1529 to begin monitoring <tt>hashchange</tt> events, and dispatching routes.
1530 </p>
1531
1532<pre>
1533$(function(){
1534 new WorkspaceController();
1535 new HelpPaneController();
1536 Backbone.history.start();
1537});
1538</pre>
1539
1540 <h2 id="Sync">Backbone.sync</h2>
1541
1542 <p>
1543 <b>Backbone.sync</b> is the function the Backbone calls every time it
1544 attempts to read or save a model to the server. By default, it uses
1545 <tt>(jQuery/Zepto).ajax</tt> to make a RESTful JSON request. You can override
1546 it in order to use a different persistence strategy, such as WebSockets,
1547 XML transport, or Local Storage.
1548 </p>
1549
1550 <p>
1551 The method signature of <b>Backbone.sync</b> is <tt>sync(method, model, success, error)</tt>
1552 </p>
1553
1554 <ul>
1555 <li><b>method</b> – the CRUD method (<tt>"create"</tt>, <tt>"read"</tt>, <tt>"update"</tt>, or <tt>"delete"</tt>)</li>
1556 <li><b>model</b> – the model to be saved (or collection to be read)</li>
1557 <li><b>success({model: ...})</b> – a callback that should be fired if the request works</li>
1558 <li><b>error({model: ...})</b> – a callback that should be fired if the request fails</li>
1559 </ul>
1560
1561 <p>
1562 With the default implementation, when <b>Backbone.sync</b> sends up a request to save
1563 a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body
1564 with content-type <tt>application/json</tt>. When returning a JSON response,
1565 send down the attributes of the model that have been changed by the server, and need
1566 to be updated on the client. When responding to a <tt>"read"</tt> request from a collection
1567 (<a href="#Collection#fetch">Collection#fetch</a>), send down an array
1568 of model attribute objects.
1569 </p>
1570
1571 <p>
1572 The default <b>sync</b> handler maps CRUD to REST like so:
1573 </p>
1574
1575 <ul>
1576 <li><b>create → POST </b><tt>/collection</tt></li>
1577 <li><b>read → GET </b><tt>/collection[/id]</tt></li>
1578 <li><b>update → PUT </b><tt>/collection/id</tt></li>
1579 <li><b>delete → DELETE </b><tt>/collection/id</tt></li>
1580 </ul>
1581
1582 <p>
1583 As an example, a Rails handler responding to an <tt>"update"</tt> call from
1584 <tt>Backbone</tt> might look like this: <i>(In real code, never use
1585 </i><tt>update_attributes</tt><i> blindly, and always whitelist the attributes
1586 you allow to be changed.)</i>
1587 </p>
1588
1589<pre>
1590def update
1591 account = Account.find params[:id]
1592 account.update_attributes params
1593 render :json => account
1594end
1595</pre>
1596
1597 <p>
1598 One more tip for Rails integration is to disable the default namespacing for
1599 <tt>to_json</tt> calls on models by setting <tt>ActiveRecord::Base.include_root_in_json = false</tt>
1600 </p>
1601
1602 <p id="Sync-emulateHTTP">
1603 <b class="header">emulateHTTP</b><code>Backbone.emulateHTTP = true</code>
1604 <br />
1605 If you want to work with a legacy web server that doesn't support Backbones's
1606 default REST/HTTP approach, you may choose to turn on <tt>Backbone.emulateHTTP</tt>.
1607 Setting this option will fake <tt>PUT</tt> and <tt>DELETE</tt> requests with
1608 a HTTP <tt>POST</tt>, and pass them under the <tt>_method</tt> parameter. Setting this option
1609 will also set an <tt>X-HTTP-Method-Override</tt> header with the true method.
1610 </p>
1611
1612<pre>
1613Backbone.emulateHTTP = true;
1614
1615model.save(); // POST to "/collection/id", with "_method=PUT" + header.
1616</pre>
1617
1618 <p id="Sync-emulateJSON">
1619 <b class="header">emulateJSON</b><code>Backbone.emulateJSON = true</code>
1620 <br />
1621 If you're working with a legacy web server that can't handle requests
1622 encoded as <tt>application/json</tt>, setting <tt>Backbone.emulateJSON = true;</tt>
1623 will cause the JSON to be serialized under a <tt>model</tt> parameter, and
1624 the request to be made with a <tt>application/x-www-form-urlencoded</tt>
1625 mime type, as if from an HTML form.
1626 </p>
1627
1628 <h2 id="View">Backbone.View</h2>
1629
1630 <p>
1631 Backbone views are almost more convention than they are code — they
1632 don't determine anything about your HTML or CSS for you, and can be used
1633 with any JavaScript templating library.
1634 The general idea is to organize your interface into logical views,
1635 backed by models, each of which can be updated independently when the
1636 model changes, without having to redraw the page. Instead of digging into
1637 a JSON object, looking up an element in the DOM, and updating the HTML by hand,
1638 you can bind your view's <tt>render</tt> function to the model's <tt>"change"</tt>
1639 event — and now everywhere that
1640 model data is displayed in the UI, it is always immediately up to date.
1641 </p>
1642
1643 <p id="View-extend">
1644 <b class="header">extend</b><code>Backbone.View.extend(properties, [classProperties])</code>
1645 <br />
1646 Get started with views by creating a custom view class. You'll want to
1647 override the <a href="#View-render">render</a> function, specify your
1648 declarative <a href="#View-delegateEvents">events</a>, and perhaps the
1649 <tt>tagName</tt>, <tt>className</tt>, or <tt>id</tt> of the View's root
1650 element.
1651 </p>
1652
1653<pre>
1654var DocumentRow = Backbone.View.extend({
1655
1656 tagName: "li",
1657
1658 className: "document-row",
1659
1660 events: {
1661 "click .icon": "open",
1662 "click .button.edit": "openEditDialog",
1663 "click .button.delete": "destroy"
1664 },
1665
1666 initialize: function() {
1667 _.bindAll(this, "render");
1668 },
1669
1670 render: function() {
1671 ...
1672 }
1673
1674});
1675</pre>
1676
1677 <p id="View-constructor">
1678 <b class="header">constructor / initialize</b><code>new View([options])</code>
1679 <br />
1680 When creating a new View, the options you pass are attached to the view
1681 as <tt>this.options</tt>, for future reference. There are several special
1682 options that, if passed, will be attached directly to the view:
1683 <tt>model</tt>, <tt>collection</tt>,
1684 <tt>el</tt>, <tt>id</tt>, <tt>className</tt>, and <tt>tagName</tt>.
1685 If the view defines an <b>initialize</b> function, it will be called when
1686 the view is first created. If you'd like to create a view that references
1687 an element <i>already</i> in the DOM, pass in the element as an option:
1688 <tt>new View({el: existingElement})</tt>
1689 </p>
1690
1691<pre>
1692var doc = Documents.first();
1693
1694new DocumentRow({
1695 model: doc,
1696 id: "document-row-" + doc.id
1697});
1698</pre>
1699
1700 <p id="View-el">
1701 <b class="header">el</b><code>view.el</code>
1702 <br />
1703 All views have a DOM element at all times (the <b>el</b> property),
1704 whether they've already been inserted into the page or not. In this
1705 fashion, views can be rendered at any time, and inserted into the DOM all
1706 at once, in order to get high-performance UI rendering with as few
1707 reflows and repaints as possible. <tt>this.el</tt> is created from the
1708 view's <tt>tagName</tt>, <tt>className</tt>, and <tt>id</tt> properties,
1709 if specified. If not, <b>el</b> is an empty <tt>div</tt>.
1710 </p>
1711
1712 <p>
1713 You may assign <b>el</b> directly if the view is being
1714 created for an element that already exists in the DOM. Use either a
1715 reference to a real DOM element, or a css selector string.
1716 </p>
1717
1718<pre class="runnable">
1719var ItemView = Backbone.View.extend({
1720 tagName: 'li'
1721});
1722
1723var BodyView = Backbone.View.extend({
1724 el: 'body'
1725});
1726
1727var item = new ItemView();
1728var body = new BodyView();
1729
1730alert(item.el + ' ' + body.el);
1731</pre>
1732
1733 <p id="View-dollar">
1734 <b class="header">$ (jQuery or Zepto)</b><code>view.$(selector)</code>
1735 <br />
1736 If jQuery or Zepto is included on the page, each view has a
1737 <b>$</b> function that runs queries scoped within the view's element. If you use this
1738 scoped jQuery function, you don't have to use model ids as part of your query
1739 to pull out specific elements in a list, and can rely much more on HTML class
1740 attributes. It's equivalent to running: <tt>$(selector, this.el)</tt>
1741 </p>
1742
1743<pre>
1744ui.Chapter = Backbone.View.extend({
1745 serialize : function() {
1746 return {
1747 title: this.$(".title").text(),
1748 start: this.$(".start-page").text(),
1749 end: this.$(".end-page").text()
1750 };
1751 }
1752});
1753</pre>
1754
1755 <p id="View-render">
1756 <b class="header">render</b><code>view.render()</code>
1757 <br />
1758 The default implementation of <b>render</b> is a no-op. Override this
1759 function with your code that renders the view template from model data,
1760 and updates <tt>this.el</tt> with the new HTML. A good
1761 convention is to <tt>return this</tt> at the end of <b>render</b> to
1762 enable chained calls.
1763 </p>
1764
1765<pre>
1766var Bookmark = Backbone.View.extend({
1767 render: function() {
1768 $(this.el).html(this.template(this.model.toJSON()));
1769 return this;
1770 }
1771});
1772</pre>
1773
1774 <p>
1775 Backbone is agnostic with respect to your preferred method of HTML templating.
1776 Your <b>render</b> function could even munge together an HTML string, or use
1777 <tt>document.createElement</tt> to generate a DOM tree. However, we suggest
1778 choosing a nice JavaScript templating library.
1779 <a href="http://github.com/janl/mustache.js">Mustache.js</a>,
1780 <a href="http://github.com/creationix/haml-js">Haml-js</a>, and
1781 <a href="http://github.com/sstephenson/eco">Eco</a> are all fine alternatives.
1782 Because <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> is already on the page,
1783 <a href="http://documentcloud.github.com/underscore/#template">_.template</a>
1784 is available, and is an excellent choice if you've already XSS-sanitized
1785 your interpolated data.
1786 </p>
1787
1788 <p>
1789 Whatever templating strategy you end up with, it's nice if you <i>never</i>
1790 have to put strings of HTML in your JavaScript. At DocumentCloud, we
1791 use <a href="http://documentcloud.github.com/jammit/">Jammit</a> in order
1792 to package up JavaScript templates stored in <tt>/app/views</tt> as part
1793 of our main <tt>core.js</tt> asset package.
1794 </p>
1795
1796 <p id="View-remove">
1797 <b class="header">remove</b><code>view.remove()</code>
1798 <br />
1799 Convenience function for removing the view from the DOM. Equivalent to calling
1800 <tt>$(view.el).remove();</tt>
1801 </p>
1802
1803 <p id="View-make">
1804 <b class="header">make</b><code>view.make(tagName, [attributes], [content])</code>
1805 <br />
1806 Convenience function for creating a DOM element of the given type (<b>tagName</b>),
1807 with optional attributes and HTML content. Used internally to create the
1808 initial <tt>view.el</tt>.
1809 </p>
1810
1811<pre class="runnable">
1812var view = new Backbone.View;
1813
1814var el = view.make("b", {className: "bold"}, "Bold! ");
1815
1816$("#make-demo").append(el);
1817</pre>
1818
1819<div id="make-demo"></div>
1820
1821 <p id="View-delegateEvents">
1822 <b class="header">delegateEvents</b><code>delegateEvents([events])</code>
1823 <br />
1824 Uses jQuery's <tt>delegate</tt> function to provide declarative callbacks
1825 for DOM events within a view.
1826 If an <b>events</b> hash is not passed directly, uses <tt>this.events</tt>
1827 as the source. Events are written in the format <tt>{"event selector": "callback"}</tt>.
1828 Omitting the <tt>selector</tt> causes the event to be bound to the view's
1829 root element (<tt>this.el</tt>). By default, <tt>delegateEvents</tt> is called
1830 within the View's constructor for you, so if you have a simple <tt>events</tt>
1831 hash, all of your DOM events will always already be connected, and you will
1832 never have to call this function yourself.
1833 </p>
1834
1835 <p>
1836 Using <b>delegateEvents</b> provides a number of advantages over manually
1837 using jQuery to bind events to child elements during <a href="#View-render">render</a>. All attached
1838 callbacks are bound to the view before being handed off to jQuery, so when
1839 the callbacks are invoked, <tt>this</tt> continues to refer to the view object. When
1840 <b>delegateEvents</b> is run again, perhaps with a different <tt>events</tt>
1841 hash, all callbacks are removed and delegated afresh — useful for
1842 views which need to behave differently when in different modes.
1843 </p>
1844
1845 <p>
1846 A view that displays a document in a search result might look
1847 something like this:
1848 </p>
1849
1850<pre>
1851var DocumentView = Backbone.View.extend({
1852
1853 events: {
1854 "dblclick" : "open",
1855 "click .icon.doc" : "select",
1856 "contextmenu .icon.doc" : "showMenu",
1857 "click .show_notes" : "toggleNotes",
1858 "click .title .lock" : "editAccessLevel",
1859 "mouseover .title .date" : "showTooltip"
1860 },
1861
1862 render: function() {
1863 $(this.el).html(this.template(this.model.toJSON()));
1864 return this;
1865 },
1866
1867 open: function() {
1868 window.open(this.model.get("viewer_url"));
1869 },
1870
1871 select: function() {
1872 this.model.set({selected: true});
1873 },
1874
1875 ...
1876
1877});
1878</pre>
1879
1880 <h2 id="examples">Examples</h2>
1881
1882 <p>
1883 <a href="http://jgn.me/">Jérôme Gravel-Niquet</a> has contributed a
1884 <a href="examples/todos/index.html">Todo List application</a>
1885 that is bundled in the repository as Backbone example. If you're wondering
1886 where to get started with Backbone in general, take a moment to
1887 <a href="docs/todos.html">read through the annotated source</a>. The app uses a
1888 <a href="docs/backbone-localstorage.html">LocalStorage adapter</a>
1889 to transparently save all of your todos within your browser, instead of
1890 sending them to a server. Jérôme also has a version hosted at
1891 <a href="http://localtodos.com/">localtodos.com</a> that uses a
1892 <a href="http://github.com/jeromegn/backbone-mootools">MooTools-backed version of Backbone</a>
1893 instead of jQuery.
1894 </p>
1895
1896 <div style="text-align: center;">
1897 <a href="examples/todos/index.html">
1898 <img src="docs/images/todos.png" alt="Todos" class="example_image" />
1899 </a>
1900 </div>
1901
1902 <p>
1903 The <a href="http://www.documentcloud.org/public/#search/">DocumentCloud workspace</a>
1904 is built on Backbone.js, with <i>Documents</i>, <i>Projects</i>,
1905 <i>Notes</i>, and <i>Accounts</i> all as Backbone models and collections.
1906 </p>
1907
1908 <div style="text-align: center;">
1909 <a href="http://www.documentcloud.org/public/#search/">
1910 <img src="docs/images/dc-workspace.png" alt="DocumentCloud Workspace" class="example_image" />
1911 </a>
1912 </div>
1913
1914 <p>
1915 <a href="http://37signals.com/">37Signals</a> used Backbone.js to create
1916 <a href="http://basecamphq.com/mobile">Basecamp Mobile</a>, the mobile version
1917 of their popular project management software. You can access all your Basecamp
1918 projects, post new messages, and comment on milestones (all represented
1919 internally as Backbone.js models).
1920 </p>
1921
1922 <div style="text-align: center;">
1923 <a href="http://basecamphq.com/mobile">
1924 <img src="docs/images/basecamp-mobile.png" alt="Basecamp Mobile" class="example_image" />
1925 </a>
1926 </div>
1927
1928 <p>
1929 Our fellow
1930 <a href="http://www.newschallenge.org/">Knight Foundation News Challenge</a>
1931 winners, <a href="http://mapbox.com/">MapBox</a>, created an open-source
1932 map design studio with Backbone.js:
1933 <a href="http://mapbox.github.com/tilemill/">TileMill</a>.
1934 TileMill lets you manage map layers based on shapefiles and rasters, and
1935 edit their appearance directly in the browser with the
1936 <a href="https://github.com/mapbox/carto">Carto styling language</a>.
1937 </p>
1938
1939 <div style="text-align: center;">
1940 <a href="http://mapbox.github.com/tilemill/">
1941 <img src="docs/images/tilemill.png" alt="TileMill" class="example_image" />
1942 </a>
1943 </div>
1944
1945 <p>
1946 <a href="http://twitter.com/elliottkember">Elliott Kember</a> and
1947 <a href="http://twitter.com/dizzyup">Hector Simpson</a> built
1948 <a href="http://instagre.at">Insta-great!</a>
1949 - a fun way to explore popular photos and interact with
1950 <a href="http://instagram.com/">Instagram</a> on the web.
1951 Elliott says, "Backbone.js and Coffeescript were insanely useful for
1952 writing clean, consistent UI code and keeping everything modular and
1953 readable, even through several code refactors. I'm in love."
1954 </p>
1955
1956 <div style="text-align: center;">
1957 <a href="http://instagre.at">
1958 <img src="docs/images/instagreat.png" alt="instagre.at" class="example_image" />
1959 </a>
1960 </div>
1961
1962 <p>
1963 <a href="http://www.twitter.com/jamesjyu">James Yu</a> used Backbone.js to
1964 create <a href="http://www.quietwrite.com/">QuietWrite</a>, an app
1965 that gives writers a clean and quiet interface to concentrate on the text itself.
1966 The editor relies on Backbone to persist document data to the server. He
1967 followed up with a Backbone.js + Rails tutorial that describes how to implement
1968 <a href="http://www.jamesyu.org/2011/01/27/cloudedit-a-backbone-js-tutorial-by-example/">CloudEdit, a simple document editing app</a>.
1969 </p>
1970
1971 <div style="text-align: center;">
1972 <a href="http://www.quietwrite.com/">
1973 <img src="docs/images/quietwrite.png" alt="QuietWrite" class="example_image" />
1974 </a>
1975 </div>
1976
1977 <p>
1978 <a href="http://twitter.com/evilchelu">Cristi Balan</a> and
1979 <a href="http://dira.ro">Irina Dumitrascu</a> created
1980 <a href="http://tzigla.com">Tzigla</a>, a collaborative drawing
1981 application where artists make tiles that connect to each other to
1982 create <a href="http://tzigla.com/boards/1">surreal drawings</a>.
1983 Backbone models help organize the code, controllers provide
1984 <a href="http://tzigla.com/boards/1#!/tiles/2-2">bookmarkable deep links</a>,
1985 and the views are rendered with
1986 <a href="https://github.com/creationix/haml-js">haml.js</a> and
1987 <a href="http://zeptojs.com/">Zepto</a>.
1988 Tzigla is written in Ruby (Rails) on the backend, and
1989 <a href="http://coffeescript.org">CoffeeScript</a> on the frontend, with
1990 <a href="http://documentcloud.github.com/jammit/">Jammit</a>
1991 prepackaging the static assets.
1992 </p>
1993
1994 <div style="text-align: center;">
1995 <a href="http://www.tzigla.com/">
1996 <img src="docs/images/tzigla.png" alt="Tzigla" class="example_image" />
1997 </a>
1998 </div>
1999
2000 <p>
2001 Michael Aufreiter is building an open source document authoring and publishing engine: <a href="http://substance.io">Substance</a>.
2002 Substance makes use of Backbone.View and Backbone.Controller, while Backbone plays well together with <a href="http://github.com/michael/data">Data.js</a>, which is used for data persistence.
2003 </p>
2004
2005 <div style="text-align: center;">
2006 <a href="http://substance.io/">
2007 <img src="docs/images/substance.png" alt="Substance" class="example_image" />
2008 </a>
2009 </div>
2010
2011 <p>
2012 <a href="http://bennolan.com/">Ben Nolan</a> created
2013 <a href="http://bennolan.com/2010/11/24/backbone-jquery-demo.html">an example "Backbone Mobile" application</a>, combining Backbone.js
2014 with <a href="http://jquerymobile.com/">jQuery Mobile</a>. You can
2015 <a href="http://bennolan.com/science/backbone-mobile/">try the app</a>
2016 in your browser, or view the
2017 <a href="https://github.com/bnolan/backbone-mobile">source code</a> on Github.
2018 </p>
2019
2020 <div style="text-align: center;">
2021 <a href="http://bennolan.com/science/backbone-mobile/">
2022 <img src="docs/images/backbone-mobile.png" alt="Backbone Mobile" class="example_image" />
2023 </a>
2024 </div>
2025
2026 <h2 id="faq">F.A.Q.</h2>
2027
2028 <p id="FAQ-events">
2029 <b class="header">Catalog of Events</b>
2030 <br />
2031 Here's a list of all of the built-in events that Backbone.js can fire.
2032 You're also free to trigger your own events on Models and Views as you
2033 see fit.
2034 </p>
2035
2036 <ul>
2037 <li><b>"add"</b> (model, collection) — when a model is added to a collection. </li>
2038 <li><b>"remove"</b> (model, collection) — when a model is removed from a collection. </li>
2039 <li><b>"refresh"</b> (collection) — when the collection's entire contents have been replaced. </li>
2040 <li><b>"change"</b> (model, collection) — when a model's attributes have changed. </li>
2041 <li><b>"change:[attribute]"</b> (model, collection) — when a specific attribute has been updated. </li>
2042 <li><b>"destrooy"</b> (model, collection) — when a model is <a href="#Model-destroy">destroyed</a>. </li>
2043 <li><b>"error"</b> (model, collection) — when a model's validation fails, or a <a href="#Model-save">save</a> call fails on the server. </li>
2044 <li><b>"route:[name]"</b> (controller) — when one of a controller's routes has matched. </li>
2045 <li><b>"all"</b> — this special event fires for <i>any</i> triggered event, passing the event name as the first argument. </li>
2046 </ul>
2047
2048 <p id="FAQ-nested">
2049 <b class="header">Nested Models & Collections</b>
2050 <br />
2051 It's common to nest collections inside of models with Backbone. For example,
2052 consider a <tt>Mailbox</tt> model that contains many <tt>Message</tt> models.
2053 One nice pattern for handling this is have a <tt>this.messages</tt> collection
2054 for each mailbox, enabling the lazy-loading of messages, when the mailbox
2055 is first opened ... perhaps with <tt>MessageList</tt> views listening for
2056 <tt>"add"</tt> and <tt>"remove"</tt> events.
2057 </p>
2058
2059<pre>
2060var Mailbox = Backbone.Model.extend({
2061
2062 initialize: function() {
2063 this.messages = new Messages;
2064 this.messages.url = '/mailbox/' + this.id + '/messages';
2065 this.messages.bind("refresh", this.updateCounts);
2066 },
2067
2068 ...
2069
2070});
2071
2072var Inbox = new Mailbox;
2073
2074// And then, when the Inbox is opened:
2075
2076Inbox.messages.fetch();
2077</pre>
2078
2079 <p id="FAQ-bootstrap">
2080 <b class="header">Loading Bootstrapped Models</b>
2081 <br />
2082 When your app first loads, it's common to have a set of initial models that
2083 you know you're going to need, in order to render the page. Instead of
2084 firing an extra AJAX request to <a href="#Collection-fetch">fetch</a> them,
2085 a nicer pattern is to have their data already bootstrapped into the page.
2086 You can then use <a href="#Collection-refresh">refresh</a> to populate your
2087 collections with the initial data. At DocumentCloud, in the
2088 <a href="http://en.wikipedia.org/wiki/ERuby">ERB</a> template for the
2089 workspace, we do something along these lines:
2090 </p>
2091
2092<pre>
2093<script>
2094 Accounts.refresh(<%= @accounts.to_json %>);
2095 Projects.refresh(<%= @projects.to_json(:collaborators => true) %>);
2096</script>
2097</pre>
2098
2099 <p id="FAQ-mvc">
2100 <b class="header">How does Backbone relate to "traditional" MVC?</b>
2101 <br />
2102 Different implementations of the
2103 <a href="http://en.wikipedia.org/wiki/Model–View–Controller">Model-View-Controller</a>
2104 pattern tend to disagree about the definition of a controller. If it helps any, in
2105 Backbone, the <a href="#View">View</a> class can also be thought of as a
2106 kind of controller, dispatching events that originate from the UI, with
2107 the HTML template serving as the true view. We call it a View because it
2108 represents a logical chunk of UI, responsible for the contents of a single
2109 DOM element.
2110 </p>
2111
2112 <p id="FAQ-this">
2113 <b class="header">Binding "this"</b>
2114 <br />
2115 Perhaps the single most common JavaScript "gotcha" is the fact that when
2116 you pass a function as a callback, it's value for <tt>this</tt> is lost. With
2117 Backbone, when dealing with <a href="#Events">events</a> and callbacks,
2118 you'll often find it useful to rely on
2119 <a href="http://documentcloud.github.com/underscore/#bind">_.bind</a> and
2120 <a href="http://documentcloud.github.com/underscore/#bindAll">_.bindAll</a>
2121 from Underscore.js. <tt>_.bind</tt> takes a function and an object to be
2122 used as <tt>this</tt>, any time the function is called in the future.
2123 <tt>_.bindAll</tt> takes an object and a list of method names: each method
2124 in the list will be bound to the object, so that it's <tt>this</tt> may
2125 not change. For example, in a <a href="#View">View</a> that listens for
2126 changes to a collection...
2127 </p>
2128
2129<pre>
2130var MessageList = Backbone.View.extend({
2131
2132 initialize: function() {
2133 _.bindAll(this, "addMessage", "removeMessage", "render");
2134
2135 var messages = this.collection;
2136 messages.bind("refresh", this.render);
2137 messages.bind("add", this.addMessage);
2138 messages.bind("remove", this.removeMessage);
2139 }
2140
2141});
2142
2143// Later, in the app...
2144
2145Inbox.messages.add(newMessage);
2146</pre>
2147
2148 <p id="FAQ-rias">
2149 <b class="header">
2150 How is Backbone different than
2151 <a href="http://www.sproutcore.com/">SproutCore</a> or
2152 <a href="http://cappuccino.org/">Cappuccino</a>?
2153 </b>
2154 <br />
2155 This question is frequently asked, and all three projects apply general
2156 <a href="http://en.wikipedia.org/wiki/Model–View–Controller">Model-View-Controller</a>
2157 principles to JavaScript applications. However, there isn't much basis
2158 for comparison. SproutCore and Cappuccino provide rich UI widgets, vast
2159 core libraries, and determine the structure of your HTML for you.
2160 Both frameworks measure in the hundreds of kilobytes when packed and
2161 gzipped, and megabytes of JavaScript, CSS, and images when loaded in the browser
2162 — there's a lot of room underneath for libraries of a more moderate scope.
2163 Backbone is a <i>4 kilobyte</i> include that provides
2164 just the core concepts of models, events, collections, views, controllers,
2165 and persistence.
2166 </p>
2167
2168 <h2 id="changelog">Change Log</h2>
2169
2170 <p>
2171 <b class="header">0.3.3</b> — <small><i>Dec 1, 2010</i></small><br />
2172 Backbone.js now supports <a href="http://zeptojs.com">Zepto</a>, alongside
2173 jQuery, as a framework for DOM manipulation and Ajax support.
2174 Implemented <a href="#Model-escape">Model#escape</a>, to efficiently handle
2175 attributes intended for HTML interpolation. When trying to persist a model,
2176 failed requests will now trigger an <tt>"error"</tt> event. The
2177 ubiquitous <tt>options</tt> argument is now passed as the final argument
2178 to all <tt>"change"</tt> events.
2179 </p>
2180
2181 <p>
2182 <b class="header">0.3.2</b> — <small><i>Nov 23, 2010</i></small><br />
2183 Bugfix for IE7 + iframe-based "hashchange" events. <tt>sync</tt> may now be
2184 overridden on a per-model, or per-collection basis. Fixed recursion error
2185 when calling <tt>save</tt> with no changed attributes, within a
2186 <tt>"change"</tt> event.
2187 </p>
2188
2189 <p>
2190 <b class="header">0.3.1</b> — <small><i>Nov 15, 2010</i></small><br />
2191 All <tt>"add"</tt> and <tt>"remove"</tt> events are now sent through the
2192 model, so that views can listen for them without having to know about the
2193 collection. Added a <tt>remove</tt> method to <a href="#View">Backbone.View</a>.
2194 <tt>toJSON</tt> is no longer called at all for <tt>'read'</tt> and <tt>'delete'</tt> requests.
2195 Backbone routes are now able to load empty URL fragments.
2196 </p>
2197
2198 <p>
2199 <b class="header">0.3.0</b> — <small><i>Nov 9, 2010</i></small><br />
2200 Backbone now has <a href="#Controller">Controllers</a> and
2201 <a href="#History">History</a>, for doing client-side routing based on
2202 URL fragments.
2203 Added <tt>emulateHTTP</tt> to provide support for legacy servers that don't
2204 do <tt>PUT</tt> and <tt>DELETE</tt>.
2205 Added <tt>emulateJSON</tt> for servers that can't accept <tt>application/json</tt>
2206 encoded requests.
2207 Added <a href="#Model-clear">Model#clear</a>, which removes all attributes
2208 from a model.
2209 All Backbone classes may now be seamlessly inherited by CoffeeScript classes.
2210 </p>
2211
2212 <p>
2213 <b class="header">0.2.0</b> — <small><i>Oct 25, 2010</i></small><br />
2214 Instead of requiring server responses to be namespaced under a <tt>model</tt>
2215 key, now you can define your own <a href="#Model-parse">parse</a> method
2216 to convert responses into attributes for Models and Collections.
2217 The old <tt>handleEvents</tt> function is now named
2218 <a href="#View-delegateEvents">delegateEvents</a>, and is automatically
2219 called as part of the View's constructor.
2220 Added a <a href="#Collection-toJSON">toJSON</a> function to Collections.
2221 Added <a href="#Collection-chain">Underscore's chain</a> to Collections.
2222 </p>
2223
2224 <p>
2225 <b class="header">0.1.2</b> — <small><i>Oct 19, 2010</i></small><br />
2226 Added a <a href="#Model-fetch">Model#fetch</a> method for refreshing the
2227 attributes of single model from the server.
2228 An <tt>error</tt> callback may now be passed to <tt>set</tt> and <tt>save</tt>
2229 as an option, which will be invoked if validation fails, overriding the
2230 <tt>"error"</tt> event.
2231 You can now tell backbone to use the <tt>_method</tt> hack instead of HTTP
2232 methods by setting <tt>Backbone.emulateHTTP = true</tt>.
2233 Existing Model and Collection data is no longer sent up unnecessarily with
2234 <tt>GET</tt> and <tt>DELETE</tt> requests. Added a <tt>rake lint</tt> task.
2235 Backbone is now published as an <a href="http://npmjs.org">NPM</a> module.
2236 </p>
2237
2238 <p>
2239 <b class="header">0.1.1</b> — <small><i>Oct 14, 2010</i></small><br />
2240 Added a convention for <tt>initialize</tt> functions to be called
2241 upon instance construction, if defined. Documentation tweaks.
2242 </p>
2243
2244 <p>
2245 <b class="header">0.1.0</b> — <small><i>Oct 13, 2010</i></small><br />
2246 Initial Backbone release.
2247 </p>
2248
2249 <p>
2250 <br />
2251 <a href="http://documentcloud.org/" title="A DocumentCloud Project" style="background:none;">
2252 <img src="http://jashkenas.s3.amazonaws.com/images/a_documentcloud_project.png" alt="A DocumentCloud Project" style="position:relative;left:-10px;" />
2253 </a>
2254 </p>
2255
2256 </div>
2257
2258 <script src="test/vendor/underscore-1.1.4.js"></script>
2259 <script src="test/vendor/jquery-1.5.js"></script>
2260 <script src="test/vendor/json2.js"></script>
2261 <script src="backbone.js"></script>
2262
2263 <script>
2264 // Set up the "play" buttons for each runnable code example.
2265 $(function() {
2266 $('.runnable').each(function() {
2267 var code = this;
2268 var button = $('<div class="run" title="Run"></div>');
2269 $(button).insertBefore(code).bind('click', function(){
2270 eval($(code).text());
2271 });
2272 });
2273 });
2274 </script>
2275
2276</body>
2277</html>