PageRenderTime 68ms CodeModel.GetById 3ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 0ms

/index.html

https://github.com/olleolleolle/backbone
HTML | 1402 lines | 1212 code | 190 blank | 0 comment | 0 complexity | af1a0b7b400428a39c35a43af458573c MD5 | raw file
   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        div.toc_title:hover {
  35          text-decoration: underline;
  36        }
  37      ul.toc_section {
  38        font-size: 11px;
  39        line-height: 14px;
  40        margin: 5px 0 0 0;
  41        padding-left: 0px;
  42        list-style-type: none;
  43        font-family: Lucida Grande;
  44      }
  45        .toc_section li {
  46          cursor: pointer;
  47          margin: 0 0 3px 0;
  48        }
  49          .toc_section li a {
  50            color: black;
  51          }
  52    div.container {
  53      position: relative;
  54      width: 550px;
  55      margin: 40px 0 50px 260px;
  56    }
  57    div.run {
  58      position: absolute;
  59      right: 15px;
  60      width: 26px; height: 18px;
  61      background: url('docs/images/arrows.png') no-repeat -26px 0;
  62    }
  63      div.run:active {
  64        background-position: -51px 0;
  65      }
  66    p, div.container ul {
  67      margin: 20px 0;
  68      width: 550px;
  69    }
  70      div.container ul {
  71        list-style: circle;
  72        font-size: 12px;
  73        padding-left: 15px;
  74      }
  75    a, a:visited {
  76      color: #444;
  77      text-decoration: none;
  78    }
  79    a:active, a:hover {
  80      color: #000;
  81      text-decoration: underline;
  82    }
  83    a img {
  84      border: 0;
  85    }
  86    h1, h2, h3, h4, h5, h6 {
  87      padding-top: 20px;
  88    }
  89      h2 {
  90        font-size: 20px;
  91      }
  92    b.header {
  93      font-size: 16px;
  94      line-height: 30px;
  95    }
  96    span.alias {
  97      font-size: 14px;
  98      font-style: italic;
  99      margin-left: 20px;
 100    }
 101    table {
 102      margin: 15px 0 0; padding: 0;
 103    }
 104      tr, td {
 105        margin: 0; padding: 0;
 106      }
 107        td {
 108          padding: 0px 15px 5px 0;
 109        }
 110    code, pre, tt {
 111      font-family: Monaco, Consolas, "Lucida Console", monospace;
 112      font-size: 12px;
 113      line-height: 18px;
 114    }
 115      tt {
 116        padding: 0px 3px;
 117        background: #fff;
 118        border: 1px solid #ddd;
 119        zoom: 1;
 120      }
 121      code {
 122        margin-left: 20px;
 123      }
 124      pre {
 125        font-size: 12px;
 126        padding: 2px 0 2px 15px;
 127        border: 4px solid #bbb; border-top: 0; border-bottom: 0;
 128        margin: 0px 0 30px;
 129      }
 130  </style>
 131</head>
 132<body>
 133
 134  <div id="sidebar" class="interface">
 135    <a class="toc_title" href="#">
 136      Backbone.js
 137    </a>
 138    <a class="toc_title" href="#Introduction">
 139      Introduction
 140    </a>
 141    <a class="toc_title" href="#Events">
 142      Events
 143    </a>
 144    <ul class="toc_section">
 145      <li><a href="#Events-bind">bind</a></li>
 146      <li><a href="#Events-unbind">unbind</a></li>
 147      <li><a href="#Events-trigger">trigger</a></li>
 148    </ul>
 149    <a class="toc_title" href="#Model">
 150      Model
 151    </a>
 152    <ul class="toc_section">
 153      <li><a href="#Model-extend">extend</a></li>
 154      <li><a href="#Model-constructor">constructor / initialize</a></li>
 155      <li><a href="#Model-get">get</a></li>
 156      <li><a href="#Model-set">set</a></li>
 157      <li><a href="#Model-unset">unset</a></li>
 158      <li><a href="#Model-id">id</a></li>
 159      <li><a href="#Model-cid">cid</a></li>
 160      <li><a href="#Model-attributes">attributes</a></li>
 161      <li>- <a href="#Model-toJSON">toJSON</a></li>
 162      <li><a href="#Model-save">save</a></li>
 163      <li><a href="#Model-destroy">destroy</a></li>
 164      <li><a href="#Model-validate">validate</a></li>
 165      <li><a href="#Model-url">url</a></li>
 166      <li><a href="#Model-clone">clone</a></li>
 167      <li><a href="#Model-isNew">isNew</a></li>
 168      <li><a href="#Model-change">change</a></li>
 169      <li><a href="#Model-hasChanged">hasChanged</a></li>
 170      <li><a href="#Model-changedAttributes">changedAttributes</a></li>
 171      <li><a href="#Model-previous">previous</a></li>
 172      <li><a href="#Model-previousAttributes">previousAttributes</a></li>
 173    </ul>
 174    <a class="toc_title" href="#Collection">
 175      Collection
 176    </a>
 177    <ul class="toc_section">
 178      <li><a href="#Collection-extend">extend</a></li>
 179      <li><a href="#Collection-model">model</a></li>
 180      <li><a href="#Collection-constructor">constructor / initialize</a></li>
 181      <li><a href="#Collection-models">models</a></li>
 182      <li><a href="#Collection-Underscore-Methods"><b>Underscore Methods (24)</b></a></li>
 183      <li><a href="#Collection-add">add</a></li>
 184      <li><a href="#Collection-remove">remove</a></li>
 185      <li><a href="#Collection-get">get</a></li>
 186      <li><a href="#Collection-getByCid">getByCid</a></li>
 187      <li><a href="#Collection-at">at</a></li>
 188      <li><a href="#Collection-length">length</a></li>
 189      <li><a href="#Collection-comparator">comparator</a></li>
 190      <li><a href="#Collection-sort">sort</a></li>
 191      <li><a href="#Collection-pluck">pluck</a></li>
 192      <li><a href="#Model-url">url</a></li>
 193      <li><a href="#Collection-fetch">fetch</a></li>
 194      <li><a href="#Collection-refresh">refresh</a></li>
 195      <li><a href="#Collection-create">create</a></li>
 196    </ul>
 197    <a class="toc_title" href="#Sync">
 198      Sync
 199    </a>
 200    <ul class="toc_section">
 201      <li><a href="#Sync">Backbone.sync</a></li>
 202    </ul>
 203    <a class="toc_title" href="#View">
 204      View
 205    </a>
 206    <ul class="toc_section">
 207      <li><a href="#View-extend">extend</a></li>
 208      <li><a href="#View-constructor">constructor / initialize</a></li>
 209      <li><a href="#View-el">el</a></li>
 210      <li><a href="#View-jQuery">$ (jQuery)</a></li>
 211      <li><a href="#View-render">render</a></li>
 212      <li><a href="#View-make">make</a></li>
 213      <li><a href="#View-handleEvents">handleEvents</a></li>
 214    </ul>
 215    <a class="toc_title" href="#changelog">
 216      Change Log
 217    </a>
 218  </div>
 219
 220  <div class="container">
 221
 222    <p>
 223      <img style="width: 385px; height: 126px;" src="docs/images/backbone.png" alt="Backbone.js" />
 224    </p>
 225
 226    <p>
 227      <a href="http://github.com/documentcloud/backbone/">Backbone</a>
 228      supplies structure to JavaScript-heavy applications by providing <b>models</b> with
 229      key-value binding and custom events, <b>collections</b> with a rich API of enumerable functions,
 230      <b>views</b> with declarative event handling, and connects it all to your
 231      existing application over a RESTful JSON interface.
 232    </p>
 233
 234    <p>
 235      The project is <a href="http://github.com/documentcloud/backbone/">hosted on GitHub</a>,
 236      and the <a href="docs/backbone.html">annotated source code</a> is available,
 237      as well as an online <a href="test/test.html">test suite</a>.
 238    </p>
 239
 240    <p>
 241      <i>
 242        Backbone is an open-source component of
 243        <a href="http://documentcloud.org/">DocumentCloud</a>.
 244      </i>
 245    </p>
 246
 247    <h2 id="downloads">
 248      Downloads &amp; Dependencies
 249      <span style="padding-left: 7px; font-size:11px; font-weight: normal;" class="interface">(Right-click, and use "Save As")</span>
 250    </h2>
 251
 252    <table>
 253      <tr>
 254        <td><a href="backbone.js">Development Version (0.1.1)</a></td>
 255        <td><i>21kb, Uncompressed with Comments</i></td>
 256      </tr>
 257      <tr>
 258        <td><a href="backbone-min.js">Production Version (0.1.1)</a></td>
 259        <td><i>2kb, Packed and Gzipped</i></td>
 260      </tr>
 261    </table>
 262
 263    <p>
 264      Backbone's only hard dependency is
 265      <a href="http://documentcloud.github.com/underscore/">Underscore.js</a>.
 266      For RESTful persistence, and DOM manipulation with
 267      <a href="#View">Backbone.View</a>,
 268      it's highly recommended to include <a href="http://jquery.com">jQuery</a>,
 269      and <a href="http://www.json.org/json2.js">json2.js</a>
 270      (both of which you may already have on the page).
 271    </p>
 272
 273    <h2 id="Introduction">Introduction</h2>
 274
 275    <p>
 276      When working on a web application that involves a lot of JavaScript, one
 277      of the first things you learn is to stop tying your data to the DOM. It's all
 278      too easy to create JavaScript applications that end up as tangled piles of
 279      jQuery selectors and callbacks, all trying frantically to keep data in
 280      sync between the HTML UI, your JavaScript logic, and the database on your
 281      server. For rich client-side applications, a more structured approach
 282      is helpful.
 283    </p>
 284
 285    <p>
 286      With Backbone, you represent your data as
 287      <a href="#Model">Models</a>, which can be created, validated, destroyed,
 288      and saved to the server. Whenever a UI action causes an attribute of
 289      a model to change, the model triggers a <i>"change"</i> event; all
 290      the <a href="#View">Views</a> that display the model's data are notified of the
 291      event, causing them to re-render. You don't have to write the glue
 292      code that looks into the DOM to find an element with a specific <i>id</i>,
 293      and update the HTML manually
 294      &mdash; when the model changes, the views simply update themselves.
 295    </p>
 296
 297    <p>
 298      <i>How is this different than
 299        <a href="http://www.sproutcore.com/">SproutCore</a> or
 300        <a href="http://cappuccino.org/">Cappuccino</a>?
 301      </i>
 302    </p>
 303
 304    <p>
 305      This question is frequently asked, and all three projects apply general
 306      <a href="http://en.wikipedia.org/wiki/Model–View–Controller">Model-View-Controller</a>
 307      principles to JavaScript applications. However, there isn't much basis
 308      for comparison. SproutCore and Cappuccino provide rich UI widgets, vast
 309      core libraries, and determine the structure of your HTML for you.
 310      Both frameworks measure in the hundreds of kilobytes when packed and
 311      gzipped, and megabytes of JavaScript, CSS, and images when loaded in the browser
 312      &mdash; there's a lot of room underneath for libraries of a more moderate scope.
 313      Backbone is a <i>2 kilobyte</i> include that provides
 314      just the core concepts of models, events, collections, views, and persistence.
 315    </p>
 316
 317    <p>
 318      Many of the examples that follow are runnable. Click the <i>play</i> button
 319      to execute them.
 320    </p>
 321
 322    <h2 id="Events">Backbone.Events</h2>
 323
 324    <p>
 325      <b>Events</b> is a module that can be mixed in to any object, giving the
 326      object the ability to bind and trigger custom named events. Events do not
 327      have to be declared before they are bound, and may take passed arguments.
 328      For example:
 329    </p>
 330
 331<pre class="runnable">
 332var object = {};
 333
 334_.extend(object, Backbone.Events);
 335
 336object.bind("alert", function(msg) {
 337  alert("Triggered " + msg);
 338});
 339
 340object.trigger("alert", "an event");
 341</pre>
 342
 343    <p id="Events-bind">
 344      <b class="header">bind</b><code>object.bind(event, callback)</code>
 345      <br />
 346      Bind a <b>callback</b> function to an object. The callback will be invoked
 347      whenever the <b>event</b> (specified by an arbitrary string identifier) is fired.
 348      If you have a large number of different events on a page, the convention is to use colons to
 349      namespace them: <tt>"poll:start"</tt>, or <tt>"change:selection"</tt>
 350    </p>
 351
 352    <p>
 353      Callbacks bound to the special
 354      <tt>"all"</tt> event will be triggered when any event occurs, and are passed
 355      the name of the event as the first argument. For example, to proxy all events
 356      from one object to another:
 357    </p>
 358
 359<pre>
 360proxy.bind("all", function(eventName) {
 361  object.trigger(eventName);
 362});
 363</pre>
 364
 365    <p id="Events-unbind">
 366      <b class="header">unbind</b><code>object.unbind([event], [callback])</code>
 367      <br />
 368      Remove a previously-bound <b>callback</b> function from an object. If no
 369      callback is specified, all callbacks for the <b>event</b> will be
 370      removed. If no event is specified, <i>all</i> event callbacks on the object
 371      will be removed.
 372    </p>
 373
 374<pre>
 375object.unbind("change", onChange);  // Removes just the onChange callback.
 376
 377object.unbind("change");            // Removes all "change" callbacks.
 378
 379object.unbind();                    // Removes all callbacks on object.
 380</pre>
 381
 382    <p id="Events-trigger">
 383      <b class="header">trigger</b><code>object.trigger(event, [*args])</code>
 384      <br />
 385      Trigger callbacks for the given <b>event</b>. Subsequent arguments to
 386      <b>trigger</b> will be passed along to the event callbacks.
 387    </p>
 388
 389    <h2 id="Model">Backbone.Model</h2>
 390
 391    <p>
 392      <b>Models</b> are the heart of any JavaScript application, containing
 393      the interactive data as well as a large part of the logic surrounding it:
 394      conversions, validations, computed properties, and access control. You
 395      extend <b>Backbone.Model</b> with your domain-specific methods, and
 396      <b>Model</b> provides a basic set of functionality for managing changes.
 397    </p>
 398
 399    <p>
 400      The following is a contrived example, but it demonstrates defining a model
 401      with a custom method, setting an attribute, and firing an event keyed
 402      to changes in that specific attribute.
 403      After running this code once, <tt>sidebar</tt> will be
 404      available in your browser's console, so you can play around with it.
 405    </p>
 406
 407<pre class="runnable">
 408var Sidebar = Backbone.Model.extend({
 409  promptColor: function() {
 410    var cssColor = prompt("Please enter a CSS color:");
 411    this.set({color: cssColor});
 412  }
 413});
 414
 415window.sidebar = new Sidebar;
 416
 417sidebar.bind('change:color', function(model, color) {
 418  $('#sidebar').css({background: color});
 419});
 420
 421sidebar.set({color: 'white'});
 422
 423sidebar.promptColor();
 424</pre>
 425
 426    <p id="Model-extend">
 427      <b class="header">extend</b><code>Backbone.Model.extend(properties, [classProperties])</code>
 428      <br />
 429      To create a <b>Model</b> class of your own, you extend <b>Backbone.Model</b>
 430      and provide instance <b>properties</b>, as well as optional
 431      <b>classProperties</b> to be attached directly to the constructor function.
 432    </p>
 433
 434    <p>
 435      <b>extend</b> correctly sets up the prototype chain, so subclasses created
 436      with <b>extend</b> can be further extended and subclassed as far as you like.
 437    </p>
 438
 439<pre>
 440var Note = Backbone.Model.extend({
 441  
 442  initialize: function() { ... },
 443
 444  author: function() { ... },
 445
 446  allowedToEdit: function(account) { ... },
 447
 448  coordinates: function() { ... }
 449
 450});
 451</pre>
 452
 453    <p>
 454      <i>
 455        Brief aside on </i><tt>super</tt>: <i>JavaScript does not provide
 456        a simple way to call super &mdash; the function of the same name defined
 457        higher on the prototype chain. If you override a core function like
 458        </i><tt>set</tt>,<i> or </i><tt>save</tt>, <i>and you want to invoke the
 459        parent object's implementation, you'll have to explicitly call it, along these lines:
 460      </i>
 461    </p>
 462    
 463<pre>
 464var Note = Backbone.Model.extend({
 465  set: function(attributes, options) {
 466    Backbone.Model.prototype.set.call(this, attributes, options);
 467    ...
 468  }
 469});
 470</pre>
 471
 472    <p id="Model-constructor">
 473      <b class="header">constructor / initialize</b><code>new Model([attributes])</code>
 474      <br />
 475      When creating an instance of a model, you can pass in the initial values
 476      of the <b>attributes</b>, which will be <a href="#Model-set">set</a> on the
 477      model. If you define an <b>initialize</b> function, it will be invoked when
 478      the model is created.
 479    </p>
 480
 481<pre>
 482new Book({
 483  title: "One Thousand and One Nights",
 484  author: "Scheherazade"
 485});
 486</pre>
 487
 488    <p id="Model-get">
 489      <b class="header">get</b><code>model.get(attribute)</code>
 490      <br />
 491      Get the current value of an attribute from the model. For example:
 492      <tt>note.get("title")</tt>
 493    </p>
 494
 495    <p id="Model-set">
 496      <b class="header">set</b><code>model.set(attributes, [options])</code>
 497      <br />
 498      Set a hash of attributes (one or many) on the model. If any of the attributes
 499      change the models state, a <tt>"change"</tt> event will be fired, unless
 500      <tt>{silent: true}</tt> is passed as an option.
 501    </p>
 502
 503    <p>
 504      If the model has a <a href="#Model-validate">validate</a> method,
 505      it will be validated before the attributes are set, and no changes will
 506      occur if the validation fails.
 507    </p>
 508
 509<pre>
 510note.set({title: "October 12", content: "Lorem Ipsum Dolor Sit Amet..."});
 511</pre>
 512
 513    <p id="Model-unset">
 514      <b class="header">unset</b><code>model.unset(attribute, [options])</code>
 515      <br />
 516      Remove an attribute by deleting it from the internal attributes hash.
 517      Fires a <tt>"change"</tt> event unless <tt>silent</tt> is passed as an option.
 518    </p>
 519
 520    <p id="Model-id">
 521      <b class="header">id</b><code>model.id</code>
 522      <br />
 523      A special property of models, the <b>id</b> is an arbitrary string
 524      (integer id or UUID). If you set the <b>id</b> in the
 525      attributes hash, it will be copied onto the model as a direct property.
 526      Models can be retrieved by id from collections, and the id is used to generate
 527      model URLs by default.
 528    </p>
 529
 530    <p id="Model-cid">
 531      <b class="header">cid</b><code>model.cid</code>
 532      <br />
 533      A special property of models, the <b>cid</b> or client id is a unique identifier
 534      automatically assigned to all models when they're first created. Client ids
 535      are handy when the model has not yet been saved to the server, and does not
 536      yet have its eventual true <b>id</b>, but already needs to be visible in the UI.
 537      Client ids take the form: <tt>c1, c2, c3 ...</tt>
 538    </p>
 539
 540    <p id="Model-attributes">
 541      <b class="header">attributes</b><code>model.attributes</code>
 542      <br />
 543      The <b>attributes</b> property is the internal hash containing the model's
 544      state. Please use <a href="#Model-set">set</a> to update the attributes instead of modifying
 545      them directly. If you'd like to retrieve and munge a copy of the model's
 546      attributes, use <a href="#Model-toJSON">toJSON</a> instead.
 547    </p>
 548
 549    <p id="Model-toJSON">
 550      <b class="header">toJSON</b><code>model.toJSON()</code>
 551      <br />
 552      Return a copy of the model's <a href="#Model-attributes">attributes</a> for JSON stringification.
 553      This can be used for persistence, serialization, or for augmentation before
 554      being handed off to a view. The name of this method is a bit confusing, as
 555      it doesn't actually return a JSON string &mdash; but I'm afraid that it's
 556      the way that the <a href="https://developer.mozilla.org/en/JSON#toJSON()_method">JavaScript API for <b>JSON.stringify</b> works</a>.
 557    </p>
 558
 559<pre class="runnable">
 560var artist = new Backbone.Model({
 561  firstName: "Wassily",
 562  lastName: "Kandinsky"
 563});
 564
 565artist.set({birthday: "December 16, 1866"});
 566
 567alert(JSON.stringify(artist));
 568</pre>
 569
 570    <p id="Model-save">
 571      <b class="header">save</b><code>model.save(attributes, [options])</code>
 572      <br />
 573      Save a model to your database (or alternative persistence layer),
 574      by delegating to <a href="#Sync">Backbone.sync</a>. If the model has a <a href="#Model-validate">validate</a>
 575      method, and validation fails, the model will not be saved. If the model
 576      <a href="#Model-isNew">isNew</a>, the save will be a <tt>"create"</tt>
 577      (HTTP <tt>POST</tt>), if the model already
 578      exists on the server, the save will be an <tt>"update"</tt> (HTTP <tt>PUT</tt>). Accepts
 579      <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which
 580      are passed <tt>(model, response)</tt> as arguments.
 581    </p>
 582
 583    <p>
 584      In the following example, notice how because the model has never been
 585      saved previously, our overridden version of <tt>Backbone.sync</tt> receives a <tt>"create"</tt> request.
 586    </p>
 587
 588<pre class="runnable">
 589Backbone.sync = function(method, model) {
 590  alert(method + ": " + JSON.stringify(model));
 591};
 592
 593var book = new Backbone.Model({
 594  title: "The Rough Riders",
 595  author: "Theodore Roosevelt"
 596});
 597
 598book.save();
 599</pre>
 600
 601    <p id="Model-destroy">
 602      <b class="header">destroy</b><code>model.destroy([options])</code>
 603      <br />
 604      Destroys the model on the server by delegating an HTTP <tt>DELETE</tt>
 605      request to <a href="#Sync">Backbone.sync</a>. Accepts
 606      <tt>success</tt> and <tt>error</tt> callbacks in the options hash.
 607    </p>
 608
 609<pre>
 610book.destroy({success: function(model, response) {
 611  ...
 612}});
 613</pre>
 614
 615    <p id="Model-validate">
 616      <b class="header">validate</b><code>model.validate(attributes)</code>
 617      <br />
 618      This method is left undefined, and you're encouraged to override it with
 619      your custom validation logic, if you have any that can be performed
 620      in JavaScript. <b>validate</b> is called before <tt>set</tt> and
 621      <tt>save</tt>, and is passed the attributes that are about to be updated.
 622      If the model and attributes are valid, don't return anything from <b>validate</b>;
 623      if the attributes are invalid, return an error of your choosing. It
 624      can be as simple as a string error message to be displayed, or a complete
 625      error object that describes the error programmatically. <tt>set</tt> and
 626      <tt>save</tt> will not continue if <b>validate</b> returns an error.
 627      Failed validations trigger an <tt>"error"</tt> event.
 628    </p>
 629
 630<pre class="runnable">
 631var Chapter = Backbone.Model.extend({
 632  validate: function(attrs) {
 633    if (attrs.end < attrs.start) {
 634      return "can't end before it starts";
 635    }
 636  }
 637});
 638
 639var one = new Chapter({
 640  title : "Chapter One: The Beginning"
 641});
 642
 643one.bind("error", function(model, error) {
 644  alert(model.get("title") + " " + error);
 645});
 646
 647one.set({
 648  start: 15,
 649  end:   10
 650});
 651</pre>
 652
 653    <p id="Model-url">
 654      <b class="header">url</b><code>model.url()</code>
 655      <br />
 656      Returns the relative URL where the model's resource would be located on
 657      the server. If your models are located somewhere else, override this method
 658      with the correct logic. Generates URLs of the form: <tt>"/[collection]/[id]"</tt>.
 659    </p>
 660
 661    <p>
 662      A model with an id of <tt>101</tt>, stored in a
 663      <a href="#Collection">Backbone.Collection</a> with a <tt>url</tt> of <tt>"/notes"</tt>,
 664      would have this URL: <tt>"/notes/101"</tt>
 665    </p>
 666
 667    <p id="Model-clone">
 668      <b class="header">clone</b><code>model.clone()</code>
 669      <br />
 670      Returns a new instance of the model with identical attributes.
 671    </p>
 672
 673    <p id="Model-isNew">
 674      <b class="header">isNew</b><code>model.isNew()</code>
 675      <br />
 676      Has this model been saved to the server yet? If the model does not yet have
 677      an <tt>id</tt>, it is considered to be new.
 678    </p>
 679
 680    <p id="Model-change">
 681      <b class="header">change</b><code>model.change()</code>
 682      <br />
 683      Manually trigger the <tt>"change"</tt> event.
 684      If you've been passing <tt>{silent: true}</tt> to the <a href="#Model-set">set</a> function in order to
 685      aggregate rapid changes to a model, you'll want to call <tt>model.change()</tt>
 686      when you're all finished.
 687    </p>
 688
 689    <p id="Model-hasChanged">
 690      <b class="header">hasChanged</b><code>model.hasChanged([attribute])</code>
 691      <br />
 692      Has the model changed since the last <tt>"change"</tt> event? If an <b>attribute</b>
 693      is passed, returns <tt>true</tt> if that specific attribute has changed.
 694    </p>
 695
 696<pre>
 697book.bind("change", function() {
 698  if (book.hasChanged("title")) {
 699    ...
 700  }
 701});
 702</pre>
 703
 704    <p id="Model-changedAttributes">
 705      <b class="header">changedAttributes</b><code>model.changedAttributes([attributes])</code>
 706      <br />
 707      Retrieve a hash of only the model's attributes that have changed. Optionally,
 708      an external <b>attributes</b> hash can be passed in, returning
 709      the attributes in that hash which differ from the model. This can be used
 710      to figure out which portions of a view should be updated, or what calls
 711      need to be made to sync the changes to the server.
 712    </p>
 713
 714    <p id="Model-previous">
 715      <b class="header">previous</b><code>model.previous(attribute)</code>
 716      <br />
 717      During a <tt>"change"</tt> event, this method can be used to get the
 718      previous value of a changed attribute.
 719    </p>
 720
 721<pre class="runnable">
 722var bill = new Backbone.Model({
 723  name: "Bill Smith"
 724});
 725
 726bill.bind("change:name", function(model, name) {
 727  alert("Changed name from " + bill.previous("name") + " to " + name);
 728});
 729
 730bill.set({name : "Bill Jones"});
 731</pre>
 732
 733    <p id="Model-previousAttributes">
 734      <b class="header">previousAttributes</b><code>model.previousAttributes()</code>
 735      <br />
 736      Return a copy of the model's previous attributes. Useful for getting a
 737      diff between versions of a model, or getting back to a valid state after
 738      an error occurs.
 739    </p>
 740
 741    <h2 id="Collection">Backbone.Collection</h2>
 742
 743    <p>
 744      Collections are ordered sets of models. You can bind callbacks to be notified
 745      when any model in the collection is changed, listen for <tt>"add"</tt> and
 746      <tt>"remove"</tt> events, <tt>fetch</tt> the collection from the server,
 747      and use a full suite of
 748      <a href="#Collection-Underscore-Methods">Underscore.js methods</a>.
 749    </p>
 750
 751    <p id="Collection-extend">
 752      <b class="header">extend</b><code>Backbone.Collection.extend(properties, [classProperties])</code>
 753      <br />
 754      To create a <b>Collection</b> class of your own, extend <b>Backbone.Collection</b>,
 755      providing instance <b>properties</b>, as well as optional <b>classProperties</b> to be attached
 756      directly to the collection's constructor function.
 757    </p>
 758    
 759    <p id="Collection-model">
 760      <b class="header">model</b><code>collection.model</code>
 761      <br />
 762      Override this property to specify the model class that the collection 
 763      contains. If defined, you can pass raw attributes objects (and arrays) to 
 764      <a href="#Collection-add">add</a>, <a href="#Collection-create">create</a>,
 765      and <a href="#Collection-refresh">refresh</a>, and the attributes will be
 766      converted into a model of the proper type.
 767    </p>
 768    
 769<pre>
 770var Library = Backbone.Collection.extend({
 771  model: Book
 772});
 773</pre>
 774
 775    <p id="Collection-constructor">
 776      <b class="header">constructor / initialize</b><code>new Collection([models], [options])</code>
 777      <br />
 778      When creating a Collection, you may choose to pass in the initial array of <b>models</b>.
 779      The collection's <a href="#Collection-comparator">comparator</a> function
 780      may be included as an option. If you define an <b>initialize</b> function, it will be
 781      invoked when the collection is created.
 782    </p>
 783
 784<pre>
 785var tabs = new TabSet([tab1, tab2, tab3]);
 786</pre>
 787
 788    <p id="Collection-models">
 789      <b class="header">models</b><code>collection.models</code>
 790      <br />
 791      Raw access to the JavaScript array of models inside of the collection. Usually you'll
 792      want to use <tt>get</tt>, <tt>at</tt>, or the <b>Underscore methods</b>
 793      to access model objects, but occasionally a direct reference to the array
 794      is desired.
 795    </p>
 796
 797    <p id="Collection-Underscore-Methods">
 798      <b class="header">Underscore Methods (24)</b>
 799      <br />
 800      Backbone proxies to <b>Underscore.js</b> to provide 24 iteration functions
 801      on <b>Backbone.Collection</b>. They aren't all documented here, but
 802      you can take a look at the Underscore documentation for the full details&hellip;
 803    </p>
 804
 805    <ul>
 806      <li><a href="http://documentcloud.github.com/underscore/#each">forEach (each)</a></li>
 807      <li><a href="http://documentcloud.github.com/underscore/#map">map</a></li>
 808      <li><a href="http://documentcloud.github.com/underscore/#reduce">reduce (foldl, inject)</a></li>
 809      <li><a href="http://documentcloud.github.com/underscore/#reduceRight">reduceRight (foldr)</a></li>
 810      <li><a href="http://documentcloud.github.com/underscore/#detect">find (detect)</a></li>
 811      <li><a href="http://documentcloud.github.com/underscore/#select">filter (select)</a></li>
 812      <li><a href="http://documentcloud.github.com/underscore/#reject">reject</a></li>
 813      <li><a href="http://documentcloud.github.com/underscore/#all">every (all)</a></li>
 814      <li><a href="http://documentcloud.github.com/underscore/#any">some (any)</a></li>
 815      <li><a href="http://documentcloud.github.com/underscore/#include">include</a></li>
 816      <li><a href="http://documentcloud.github.com/underscore/#invoke">invoke</a></li>
 817      <li><a href="http://documentcloud.github.com/underscore/#max">max</a></li>
 818      <li><a href="http://documentcloud.github.com/underscore/#min">min</a></li>
 819      <li><a href="http://documentcloud.github.com/underscore/#sortBy">sortBy</a></li>
 820      <li><a href="http://documentcloud.github.com/underscore/#sortedIndex">sortedIndex</a></li>
 821      <li><a href="http://documentcloud.github.com/underscore/#toArray">toArray</a></li>
 822      <li><a href="http://documentcloud.github.com/underscore/#size">size</a></li>
 823      <li><a href="http://documentcloud.github.com/underscore/#first">first</a></li>
 824      <li><a href="http://documentcloud.github.com/underscore/#rest">rest</a></li>
 825      <li><a href="http://documentcloud.github.com/underscore/#last">last</a></li>
 826      <li><a href="http://documentcloud.github.com/underscore/#without">without</a></li>
 827      <li><a href="http://documentcloud.github.com/underscore/#indexOf">indexOf</a></li>
 828      <li><a href="http://documentcloud.github.com/underscore/#lastIndexOf">lastIndexOf</a></li>
 829      <li><a href="http://documentcloud.github.com/underscore/#isEmpty">isEmpty</a></li>
 830    </ul>
 831
 832<pre>
 833Books.each(function(book) {
 834  book.publish();
 835});
 836
 837var titles = Books.map(function(book) {
 838  return book.get("title");
 839});
 840
 841var publishedBooks = Books.filter(function(book) {
 842  return book.get("published") === true;
 843});
 844
 845var alphabetical = Books.sortBy(function(book) {
 846  return book.author.get("name").toLowerCase();
 847});
 848</pre>
 849
 850    <p id="Collection-add">
 851      <b class="header">add</b><code>collection.add(models, [options])</code>
 852      <br />
 853      Add a model (or an array of models) to the collection. Fires an <tt>"add"</tt>
 854      event, which you can pass <tt>{silent: true}</tt> to suppress. If a
 855      <a href="#Collection-model">model</a> property is defined, you may also pass
 856      raw attributes objects.
 857    </p>
 858
 859<pre class="runnable">
 860var ships = new Backbone.Collection;
 861
 862ships.bind("add", function(ship) {
 863  alert("Ahoy " + ship.get("name") + "!");
 864});
 865
 866ships.add([
 867  {name: "Flying Dutchman"},
 868  {name: "Black Pearl"}
 869]);
 870</pre>
 871
 872    <p id="Collection-remove">
 873      <b class="header">remove</b><code>collection.remove(models, [options])</code>
 874      <br />
 875      Remove a model (or an array of models) from the collection. Fires a
 876      <tt>"remove"</tt> event, which you can use <tt>silent</tt>
 877      to suppress.
 878    </p>
 879
 880    <p id="Collection-get">
 881      <b class="header">get</b><code>collection.get(id)</code>
 882      <br />
 883      Get a model from a collection, specified by <b>id</b>.
 884    </p>
 885
 886<pre>
 887var book = Library.get(110);
 888</pre>
 889
 890    <p id="Collection-getByCid">
 891      <b class="header">getByCid</b><code>collection.getByCid(cid)</code>
 892      <br />
 893      Get a model from a collection, specified by client id. The client id
 894      is the <tt>.cid</tt> property of the model, automatically assigned whenever
 895      a model is created. Useful for models which have not yet been saved to
 896      the server, and do not yet have true ids.
 897    </p>
 898
 899    <p id="Collection-at">
 900      <b class="header">at</b><code>collection.at(index)</code>
 901      <br />
 902      Get a model from a collection, specified by index. Useful if your collection
 903      is sorted, and if your collection isn't sorted, <b>at</b> will still
 904      retrieve models in insertion order.
 905    </p>
 906
 907    <p id="Collection-length">
 908      <b class="header">length</b><code>collection.length</code>
 909      <br />
 910      Like an array, a Collection maintains a <tt>length</tt> property, counting
 911      the number of models it contains.
 912    </p>
 913
 914    <p id="Collection-comparator">
 915      <b class="header">comparator</b><code>collection.comparator</code>
 916      <br />
 917      By default there is no <b>comparator</b> function on a collection.
 918      If you define a comparator, it will be used to maintain
 919      the collection in sorted order. This means that as models are added,
 920      they are inserted at the correct index in <tt>collection.models</tt>.
 921      Comparator functions take a model and return a numeric or string value
 922      by which the model should be ordered relative to others.
 923    </p>
 924
 925    <p>
 926      Note how even though all of the chapters in this example are added backwards,
 927      they come out in the proper order:
 928    </p>
 929
 930<pre class="runnable">
 931var Chapter  = Backbone.Model;
 932var chapters = new Backbone.Collection;
 933
 934chapters.comparator = function(chapter) {
 935  return chapter.get("page");
 936};
 937
 938chapters.add(new Chapter({page: 9, title: "The End"}));
 939chapters.add(new Chapter({page: 5, title: "The Middle"}));
 940chapters.add(new Chapter({page: 1, title: "The Beginning"}));
 941
 942alert(chapters.pluck('title'));
 943</pre>
 944
 945    <p>
 946      <i>
 947        Brief aside: This comparator function is different than JavaScript's regular
 948        "sort", which must return </i><tt>0</tt>, <tt>1</tt>, or <tt>-1</tt>,<i>
 949        and is more similar to a </i><tt>sortBy</tt><i> &mdash; a much nicer API.
 950      </i>
 951    </p>
 952
 953    <p id="Collection-sort">
 954      <b class="header">sort</b><code>collection.sort([options])</code>
 955      <br />
 956      Force a collection to re-sort itself. You don't need to call this under
 957      normal circumstances, as a collection with a <a href="#Collection-comparator">comparator</a> function
 958      will maintain itself in proper sort order at all times. Calling <b>sort</b> 
 959      triggers the collection's <tt>"refresh"</tt> event, unless silenced by passing
 960      <tt>{silent: true}</tt>
 961    </p>
 962
 963    <p id="Collection-pluck">
 964      <b class="header">pluck</b><code>collection.pluck(attribute)</code>
 965      <br />
 966      Pluck an attribute from each model in the collection. Equivalent to calling
 967      <tt>map</tt>, and returning a single attribute from the iterator.
 968    </p>
 969
 970<pre class="runnable">
 971var stooges = new Backbone.Collection([
 972  new Backbone.Model({name: "Curly"}),
 973  new Backbone.Model({name: "Larry"}),
 974  new Backbone.Model({name: "Moe"})
 975]);
 976
 977var names = stooges.pluck("name");
 978
 979alert(JSON.stringify(names));
 980</pre>
 981
 982    <p id="Collection-url">
 983      <b class="header">url</b><code>collection.url or collection.url()</code>
 984      <br />
 985      Set the <b>url</b> property (or function) on a collection to reference
 986      its location on the server. Models within the collection will use <b>url</b>
 987      to construct URLs of their own.
 988    </p>
 989
 990<pre>
 991var Notes = Backbone.Collection.extend({
 992  url: '/notes'
 993});
 994
 995// Or, something more sophisticated:
 996
 997var Notes = Backbone.Collection.extend({
 998  url: function() {
 999    return this.document.url() + '/notes';
1000  }
1001});
1002</pre>
1003
1004    <p id="Collection-fetch">
1005      <b class="header">fetch</b><code>collection.fetch([options])</code>
1006      <br />
1007      Fetch the default set of models for this collection from the server,
1008      refreshing the collection when they arrive. The <b>options</b> hash takes
1009      <tt>success</tt> and <tt>error</tt>
1010      callbacks which will be passed <tt>(collection, response)</tt> as arguments.
1011      When the model data returns from the server, the collection will
1012      <a href="#Collection-refresh">refresh</a>.
1013      Delegates to <a href="#Sync">Backbone.sync</a>
1014      under the covers, for custom persistence strategies.
1015    </p>
1016
1017    <p>
1018      The server handler for <b>fetch</b> requests should return a JSON list of
1019      models, namespaced under "models": <tt>{"models": [...]}</tt> &mdash;
1020      instead of returning the 
1021      array directly, we ask you to namespace your models like this by default, 
1022      so that it's possible to send down out-of-band information 
1023      for things like pagination or error states.
1024    </p>
1025
1026<pre class="runnable">
1027Backbone.sync = function(method, model) {
1028  alert(method + ": " + model.url);
1029};
1030
1031var Accounts = new Backbone.Collection;
1032Accounts.url = '/accounts';
1033
1034Accounts.fetch();
1035</pre>
1036
1037    <p>
1038      Note that <b>fetch</b> should not be used to populate collections on
1039      page load &mdash; all models needed at load time should already be
1040      bootstrapped in to place. <b>fetch</b> is intended for lazily-loading models
1041      for interfaces that are not needed immediately: for example, documents
1042      with collections of notes that may be toggled open and closed.
1043    </p>
1044    
1045    <p id="Collection-refresh">
1046      <b class="header">refresh</b><code>collection.refresh(models, [options])</code>
1047      <br />
1048      Adding and removing models one at a time is all well and good, but sometimes
1049      you have so many models to change that you'd rather just update the collection
1050      in bulk. Use <b>refresh</b> to replace a collection with a new list
1051      of models (or attribute hashes), triggering a single <tt>"refresh"</tt> event
1052      at the end. Pass <tt>{silent: true}</tt> to suppress the <tt>"refresh"</tt> event.
1053    </p>
1054    
1055    <p>
1056      Here's an example using <b>refresh</b> to bootstrap a collection during initial page load,
1057      in a Rails application.
1058    </p>
1059    
1060<pre>
1061&lt;script&gt;
1062  Accounts.refresh(&lt;%= @accounts.to_json %&gt;);
1063&lt;/script&gt;
1064</pre>
1065
1066    <p id="Collection-create">
1067      <b class="header">create</b><code>collection.create(attributes, [options])</code>
1068      <br />
1069      Convenience to create a new instance of a model within a collection.
1070      Equivalent to instantiating a model with a hash of attributes,
1071      saving the model to the server, and adding the model to the set after being
1072      successfully created. Returns
1073      the model, or <tt>false</tt> if a validation error prevented the
1074      model from being created. In order for this to work, your should set the
1075      <a href="#Collection-model">model</a> property of the collection.
1076    </p>
1077
1078<pre>
1079var Library = Backbone.Collection.extend({
1080  model: Book
1081});
1082
1083var NYPL = new Library;
1084
1085var othello = NYPL.create({
1086  title: "Othello",
1087  author: "William Shakespeare"
1088});
1089</pre>
1090
1091    <h2 id="Sync">Backbone.sync</h2>
1092
1093    <p>
1094      <b>Backbone.sync</b> is the function the Backbone calls every time it
1095      attempts to read or save a model to the server. By default, it uses
1096      <tt>jQuery.ajax</tt> to make a RESTful JSON request. You can override
1097      it in order to use a different persistence strategy, such as WebSockets,
1098      XML transport, or Local Storage.
1099    </p>
1100
1101    <p>
1102      The method signature of <b>Backbone.sync</b> is <tt>sync(method, model, success, error)</tt>
1103    </p>
1104
1105    <ul>
1106      <li><b>method</b> – the CRUD method (<tt>"create"</tt>, <tt>"read"</tt>, <tt>"update"</tt>, or <tt>"delete"</tt>)</li>
1107      <li><b>model</b> – the model to be saved (or collection to be read)</li>
1108      <li><b>success({model: ...})</b> – a callback that should be fired if the request works</li>
1109      <li><b>error({model: ...})</b> – a callback that should be fired if the request fails</li>
1110    </ul>
1111
1112    <p>
1113      When formulating server responses for <b>Backbone.sync</b> requests,
1114      model attributes will be sent up, serialized as JSON, under the <tt>model</tt>
1115      parameter. When returning a JSON response, send down the model's representation
1116      under the <tt>model</tt> key, and other keys can be used for additional out-of-band
1117      information. When responding to a <tt>"read"</tt> request from a collection,
1118      send down the array of model attribute hashes under the <tt>models</tt> key.
1119    </p>
1120
1121    <p>
1122      For example, a Rails handler responding to an <tt>"update"</tt> call from
1123      <b>Backbone.sync</b> would look like this: <i>(In real code, never use
1124      </i><tt>update_attributes</tt><i> blindly, and always whitelist the attributes
1125      you allow to be changed.)</i>
1126    </p>
1127
1128<pre>
1129def update
1130  account = Account.find(params[:id])
1131  account.update_attributes JSON.parse params[:model]
1132  render :json => {:model => account}
1133end
1134</pre>
1135
1136    <h2 id="View">Backbone.View</h2>
1137
1138    <p>
1139      Backbone views are almost more convention than they are code &mdash; they
1140      don't determine anything about your HTML or CSS for you, and can be used
1141      with any JavaScript templating library.
1142      The general idea is to organize your interface into logical views,
1143      backed by models, each of which can be updated independently when the
1144      model changes, without having to redraw the page. Instead of digging into
1145      a JSON object, looking up an element in the DOM, and updating the HTML by hand,
1146      it should look more like:
1147      <tt>model.bind('change', renderView)</tt> &mdash; and now everywhere that
1148      model data is displayed in the UI, it is always immediately up to date.
1149    </p>
1150
1151    <p id="View-extend">
1152      <b class="header">extend</b><code>Backbone.View.extend(properties, [classProperties])</code>
1153      <br />
1154      Get started with views by creating a custom view class. You'll want to
1155      override the <a href="#View-render">render</a> function, specify your
1156      declarative <a href="#View-handleEvents">events</a>, and perhaps the
1157      <tt>tagName</tt>, <tt>className</tt>, or <tt>id</tt> of the View's root
1158      element.
1159    </p>
1160
1161<pre>
1162var DocumentRow = Backbone.View.extend({
1163
1164  tagName: "li",
1165
1166  className: "document-row",
1167
1168  events: {
1169    "click .icon":          "open",
1170    "click .button.edit":   "openEditDialog",
1171    "click .button.delete": "destroy"
1172  },
1173  
1174  initialize: function() {
1175    _.bindAll(this, "render");
1176  },
1177
1178  render: function() {
1179    ...
1180  }
1181
1182});
1183</pre>
1184
1185    <p id="View-constructor">
1186      <b class="header">constructor / initialize</b><code>new View([options])</code>
1187      <br />
1188      When creating a new View, the options you pass are attached to the view
1189      as <tt>this.options</tt>, for future reference. There are several special
1190      options that, if passed, will be attached directly to the view:
1191      <tt>model</tt>, <tt>collection</tt>,
1192      <tt>el</tt>, <tt>id</tt>, <tt>className</tt>, and <tt>tagName</tt>.
1193      If the view defines an <b>initialize</b> function, it will be called when 
1194      the view is first created. If you'd like to create a view that references
1195      an element <i>already</i> in the DOM, pass in the element as an option:
1196      <tt>new View({el: existingElement})</tt>
1197    </p>
1198
1199<pre>
1200var doc = Documents.first();
1201
1202new DocumentRow({
1203  model: doc,
1204  id: "document-row-" + doc.id
1205});
1206</pre>
1207
1208    <p id="View-el">
1209      <b class="header">el</b><code>view.el</code>
1210      <br />
1211      All views have a DOM element at all times (the <b>el</b> property),
1212      whether they've already been inserted into the page or not. In this
1213      fashion, views can be rendered at any time, and inserted into the DOM all
1214      at once, in order to get high-performance UI rendering with as few
1215      reflows and repaints as possible.
1216    </p>
1217
1218    <p>
1219      <tt>this.el</tt> is created from the view's <tt>tagName</tt>, <tt>className</tt>,
1220      and <tt>id</tt> properties, if specified. If not, <b>el</b> is an empty <tt>div</tt>.
1221    </p>
1222
1223    <p id="View-jQuery">
1224      <b class="header">$ (jQuery)</b><code>view.$(selector)</code>
1225      <br />
1226      If jQuery is included on the page, each view has a <b>$</b> or <b>jQuery</b>
1227      function that runs queries scoped within the view's element. If you use this
1228      scoped jQuery function, you don't have to use model ids as part of your query
1229      to pull out specific elements in a list, and can rely much more on HTML class
1230      attributes. It's equivalent to running: <tt>$(selector, this.el)</tt>
1231    </p>
1232
1233<pre>
1234ui.Chapter = Backbone.View.extend({
1235  serialize : function() {
1236    return {
1237      title: this.$(".title").text(),
1238      start: this.$(".start-page").text(),
1239      end:   this.$(".end-page").text()
1240    };
1241  }
1242});
1243</pre>
1244
1245    <p id="View-render">
1246      <b class="header">render</b><code>view.render()</code>
1247      <br />
1248      The default implementation of <b>render</b> is a no-op. Override this
1249      function with your code that renders the view template from model data,
1250      and updates <tt>this.el</tt> with the new HTML. A good
1251      convention is to <tt>return this</tt> at the end of <b>render</b> to
1252      enable chained calls.
1253    </p>
1254
1255<pre>
1256var Bookmark = Backbone.View.extend({
1257  render: function() {
1258    $(this.el).html(this.template(this.model.toJSON()));
1259    return this;
1260  }
1261});
1262</pre>
1263
1264    <p>
1265      Backbone is agnostic with respect to your preferred method of HTML templating.
1266      Your <b>render</b> function could even munge together an HTML string, or use
1267      <tt>document.createElement</tt> to generate a DOM tree. However, we suggest
1268      choosing a nice JavaScript templating library. 
1269      <a href="http://github.com/janl/mustache.js">Mustache.js</a>, 
1270      <a href="http://github.com/creationix/haml-js">Haml-js</a>, and
1271      <a href="http://github.com/sstephenson/eco">Eco</a> are all fine alternatives. 
1272      Because <a href="http://documentcloud.github.com/underscore/">Underscore.js</a> is already on the page,
1273      <a href="http://documentcloud.github.com/underscore/#template">_.template</a>
1274      is available, and is an excellent choice if you've already XSS-sanitized
1275      your interpolated data.
1276    </p>
1277    
1278    <p>
1279      Whatever templating strategy you end up with, it's nice if you <i>never</i> 
1280      have to put strings of HTML in your JavaScript. At DocumentCloud, we
1281      use <a href="http://documentcloud.github.com/jammit/">Jammit</a> in order
1282      to package up JavaScript templates stored in <tt>/app/views</tt> as part
1283      of our main <tt>core.js</tt> asset package.
1284    </p>
1285
1286    <p id="View-make">
1287      <b class="header">make</b><code>view.make(tagName, [attributes], [content])</code>
1288      <br />
1289      Convenience function for creating a DOM element of the given type (<b>tagName</b>),
1290      with optional attributes and HTML content. Used internally to create the
1291      initial <tt>view.el</tt>.
1292    </p>
1293
1294<pre class="runnable">
1295var view = new Backbone.View;
1296
1297var el = view.make("b", {className: "bold"}, "Bold! ");
1298
1299$("#make-demo").append(el);
1300</pre>
1301
1302<div id="make-demo"></div>
1303
1304    <p id="View-handleEvents">
1305      <b class="header">handleEvents</b><code>handleEvents([events])</code>
1306      <br />
1307      Uses jQuery's <tt>delegate</tt> function to provide declarative callbacks
1308      for DOM events within a view.
1309      If an <b>events</b> hash is not passed directly, uses <tt>this.events</tt>
1310      as the source. Events are written in the format <tt>{"event selector": "callback"}</tt>.
1311      Omitting the <tt>selector</tt> causes the event to be bound to the view's
1312      root element (<tt>this.el</tt>).
1313    </p>
1314
1315    <p>
1316      Using <b>handleEvents</b> provides a number of advantages over manually
1317      using jQuery to bind events to child elements during <a href="#View-render">render</a>. All attached
1318      callbacks are bound to the view before being handed off to jQuery, so when
1319      the callbacks are invoked, <tt>this</tt> continues to refer to the view object. When
1320      <b>handleEvents</b> is run again, perhaps with a different <tt>events</tt>
1321      hash, all callbacks are removed and delegated afresh &mdash; useful for
1322      views which need to behave differently when in different modes.
1323    </p>
1324
1325    <p>
1326      A view that displays a document in a search result might look
1327      something like this:
1328    </p>
1329
1330<pre>
1331var DocumentView = Backbone.View.extend({
1332
1333  events: {
1334    "dblclick"                : "open",
1335    "click .icon.doc"         : "select",
1336    "contextmenu .icon.doc"   : "showMenu",
1337    "click .show_notes"       : "toggleNotes",
1338    "click .title .lock"      : "editAccessLevel",
1339    "mouseover .title .date"  : "showTooltip"
1340  },
1341
1342  render: function() {
1343    $(this.el).html(this.template(this.model.toJSON()));
1344    this.handleEvents();
1345    return this;
1346  },
1347
1348  open: function() {
1349    window.open(this.model.get("viewer_url"));
1350  },
1351
1352  select: function() {
1353    this.model.set({selected: true});
1354  },
1355
1356  ...
1357
1358});
1359</pre>
1360
1361    <h2 id="changelog">Change Log</h2>
1362    
1363    <p>
1364      <b class="header">0.1.1</b> &mdash; <small><i>Oct 14, 2010</i></small><br />
1365      Added a convention for <tt>initialize</tt> functions to be called
1366      upon instance construction, if defined. Documentation tweaks.
1367    </p>
1368
1369    <p>
1370      <b class="header">0.1.0</b> &mdash; <small><i>Oct 13, 2010</i></small><br />
1371      Initial Backbone release.
1372    </p>
1373
1374    <p>
1375      <br />
1376      <a href="http://documentcloud.org/" title="A DocumentCloud Project" style="background:none;">
1377        <img src="http://jashkenas.s3.amazonaws.com/images/a_documentcloud_project.png" alt="A DocumentCloud Project" style="position:relative;left:-10px;" />
1378      </a>
1379    </p>
1380
1381  </div>
1382
1383  <script src="test/vendor/underscore-1.1.0.js"></script>
1384  <script src="test/vendor/jquery-1.4.2.js"></script>
1385  <script src="test/vendor/json2.js"></script>
1386  <script src="backbone.js"></script>
1387
1388  <script>
1389    // Set up the "play" buttons for each runnable code example.
1390    $(function() {
1391      $('.runnable').each(function() {
1392        var code = this;
1393        var button = $('<div class="run" title="Run"></div>');
1394        $(button).insertBefore(code).bind('click', function(){
1395          eval($(code).text());
1396        });
1397      });
1398    });
1399  </script>
1400
1401</body>
1402</html>