/index.html
HTML | 5260 lines | 4638 code | 622 blank | 0 comment | 0 complexity | 25c9461c9eb7dd9ad1f9429821ad8a79 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 <meta name="viewport" content="width=device-width"> 7 <link rel="canonical" href="http://backbonejs.org" /> 8 <title>Backbone.js</title> 9 <style> 10 body { 11 font-size: 14px; 12 line-height: 22px; 13 font-family: Helvetica Neue, Helvetica, Arial; 14 background: #f4f4f4 url(docs/images/background.png); 15 } 16 .interface { 17 font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif !important; 18 } 19 div#sidebar { 20 background: #fff; 21 position: fixed; 22 z-index: 10; 23 top: 0; left: 0; bottom: 0; 24 width: 200px; 25 overflow-y: auto; 26 overflow-x: hidden; 27 -webkit-overflow-scrolling: touch; 28 padding: 15px 0 30px 30px; 29 border-right: 1px solid #bbb; 30 box-shadow: 0 0 20px #ccc; -webkit-box-shadow: 0 0 20px #ccc; -moz-box-shadow: 0 0 20px #ccc; 31 } 32 a.toc_title, a.toc_title:visited { 33 display: block; 34 color: black; 35 font-weight: bold; 36 margin-top: 15px; 37 } 38 a.toc_title:hover { 39 text-decoration: underline; 40 } 41 #sidebar .version { 42 font-size: 10px; 43 font-weight: normal; 44 } 45 ul.toc_section { 46 font-size: 11px; 47 line-height: 14px; 48 margin: 5px 0 0 0; 49 padding-left: 0px; 50 list-style-type: none; 51 font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif; 52 } 53 .toc_section li { 54 cursor: pointer; 55 margin: 0 0 3px 0; 56 } 57 .toc_section li a { 58 text-decoration: none; 59 color: black; 60 } 61 .toc_section li a:hover { 62 text-decoration: underline; 63 } 64 input#function_filter { 65 width: 80%; 66 } 67 div.container { 68 position: relative; 69 width: 550px; 70 margin: 40px 0 50px 260px; 71 } 72 img#logo { 73 width: 450px; 74 height: 80px; 75 } 76 div.run { 77 position: absolute; 78 right: 15px; 79 width: 26px; height: 18px; 80 background: url('docs/images/arrows.png') no-repeat -26px 0; 81 } 82 div.run:active { 83 background-position: -51px 0; 84 } 85 p, div.container ul { 86 margin: 25px 0; 87 width: 550px; 88 } 89 p.warning { 90 font-size: 12px; 91 line-height: 18px; 92 font-style: italic; 93 } 94 div.container ul { 95 list-style: circle; 96 padding-left: 15px; 97 font-size: 13px; 98 line-height: 18px; 99 } 100 div.container ul li { 101 margin-bottom: 10px; 102 } 103 div.container ul.small { 104 font-size: 12px; 105 } 106 a, a:visited { 107 color: #444; 108 } 109 a:active, a:hover { 110 color: #000; 111 } 112 a.punch { 113 display: inline-block; 114 background: #4162a8; 115 border-top: 1px solid #38538c; 116 border-right: 1px solid #1f2d4d; 117 border-bottom: 1px solid #151e33; 118 border-left: 1px solid #1f2d4d; 119 -webkit-border-radius: 4px; 120 -moz-border-radius: 4px; 121 -ms-border-radius: 4px; 122 -o-border-radius: 4px; 123 border-radius: 4px; 124 -webkit-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 125 -moz-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 126 -ms-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 127 -o-box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 128 box-shadow: inset 0 1px 10px 1px #5c8bee, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 129 color: #fff; 130 font: bold 14px "helvetica neue", helvetica, arial, sans-serif; 131 line-height: 1; 132 margin-bottom: 15px; 133 padding: 8px 0 10px 0; 134 text-align: center; 135 text-shadow: 0px -1px 1px #1e2d4d; 136 text-decoration: none; 137 width: 225px; 138 -webkit-background-clip: padding-box; } 139 a.punch:hover { 140 -webkit-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 141 -moz-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 142 -ms-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 143 -o-box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 144 box-shadow: inset 0 0px 20px 1px #87adff, 0px 1px 0 #1d2c4d, 0 6px 0px #1f3053, 0 8px 4px 1px #111111; 145 cursor: pointer; } 146 a.punch:active { 147 -webkit-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111; 148 -moz-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111; 149 -ms-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111; 150 -o-box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111; 151 box-shadow: inset 0 1px 10px 1px #5c8bee, 0 1px 0 #1d2c4d, 0 2px 0 #1f3053, 0 4px 3px 0 #111111; 152 margin-top: 5px; margin-bottom: 10px; } 153 a img { 154 border: 0; 155 } 156 a.travis-badge { 157 display: block; 158 } 159 h1, h2, h3, h4, h5, h6 { 160 padding-top: 20px; 161 } 162 h2 { 163 font-size: 22px; 164 } 165 b.header { 166 font-size: 18px; 167 line-height: 35px; 168 } 169 span.alias { 170 font-size: 14px; 171 font-style: italic; 172 margin-left: 20px; 173 } 174 table { 175 margin: 15px 0 0; padding: 0; 176 } 177 tr, td { 178 margin: 0; padding: 0; 179 } 180 td { 181 padding: 0px 15px 5px 0; 182 } 183 table .rule { 184 height: 1px; 185 background: #ccc; 186 margin: 5px 0; 187 } 188 code, pre, tt { 189 font-family: Monaco, Consolas, "Lucida Console", monospace; 190 font-size: 12px; 191 line-height: 18px; 192 font-style: normal; 193 } 194 tt { 195 padding: 0px 3px; 196 background: #fff; 197 border: 1px solid #ddd; 198 zoom: 1; 199 } 200 code { 201 margin-left: 20px; 202 } 203 pre { 204 font-size: 12px; 205 padding: 2px 0 2px 15px; 206 border: 4px solid #bbb; border-top: 0; border-bottom: 0; 207 margin: 0px 0 25px; 208 } 209 img.example_image { 210 margin: 0px auto; 211 } 212 img.example_retina { 213 margin: 20px; 214 box-shadow: 0 8px 15px rgba(0,0,0,0.4); 215 } 216 @media only screen and (-webkit-max-device-pixel-ratio: 1) and (max-width: 600px), 217 only screen and (max--moz-device-pixel-ratio: 1) and (max-width: 600px) { 218 div#sidebar { 219 display: none; 220 } 221 img#logo { 222 max-width: 450px; 223 width: 100%; 224 height: auto; 225 } 226 div.container { 227 width: auto; 228 margin-left: 15px; 229 margin-right: 15px; 230 } 231 p, div.container ul { 232 width: auto; 233 } 234 } 235 @media only screen and (-webkit-min-device-pixel-ratio: 1.5) and (max-width: 640px), 236 only screen and (-o-min-device-pixel-ratio: 3/2) and (max-width: 640px), 237 only screen and (min-device-pixel-ratio: 1.5) and (max-width: 640px) { 238 img { 239 max-width: 100%; 240 height: auto; 241 } 242 div#sidebar { 243 -webkit-overflow-scrolling: initial; 244 position: relative; 245 width: 90%; 246 height: 120px; 247 left: 0; 248 top: -7px; 249 padding: 10px 0 10px 30px; 250 border: 0; 251 } 252 img#logo { 253 width: auto; 254 height: auto; 255 } 256 div.container { 257 margin: 0; 258 width: 100%; 259 } 260 p, div.container ul { 261 max-width: 98%; 262 overflow-x: scroll; 263 } 264 table { 265 position: relative; 266 } 267 tr:first-child td { 268 padding-bottom: 25px; 269 } 270 td.text { 271 line-height: 12px; 272 padding: 0; 273 position: absolute; 274 left: 0; 275 top: 48px; 276 } 277 tr:last-child td.text { 278 top: 122px; 279 } 280 pre { 281 overflow: scroll; 282 } 283 } 284 img.figure { 285 width: 100%; 286 } 287 div.columns { 288 display: table; 289 table-layout: fixed; 290 width: 100%; 291 } 292 div.columns ul { 293 margin: 10px 0; 294 } 295 div.col-50 { 296 display: table-cell; 297 width: 50%; 298 } 299 </style> 300</head> 301<body> 302 303 <div id="sidebar" class="interface"> 304 305 <a class="toc_title" href="#"> 306 Backbone.js <span class="version">(1.4.0)</span> 307 </a> 308 <ul class="toc_section"> 309 <li>» <a href="http://github.com/jashkenas/backbone">GitHub Repository</a></li> 310 <li>» <a href="docs/backbone.html">Annotated Source</a></li> 311 </ul> 312 313 <input id="function_filter" placeholder="Filter" type="text" autofocus /> 314 315 <div class="searchable_section"> 316 <a class="toc_title" href="#Getting-started"> 317 Getting Started 318 </a> 319 <ul class="toc_section"> 320 <li data-name="Introduction">- <a href="#Getting-started">Introduction</a></li> 321 <li data-name="Models and Views">– <a href="#Model-View-separation">Models and Views</a></li> 322 <li data-name="Collections">– <a href="#Model-Collections">Collections</a></li> 323 <li data-name="API Integration">– <a href="#API-integration">API Integration</a></li> 324 <li data-name="Rendering">– <a href="#View-rendering">Rendering</a></li> 325 <li data-name="Routing">– <a href="#Routing">Routing</a></li> 326 </ul> 327 </div> 328 329 <div class="searchable_section"> 330 <a class="toc_title" href="#Events"> 331 Events 332 </a> 333 <ul class="toc_section"> 334 <li data-name="on">– <a href="#Events-on">on</a></li> 335 <li data-name="off">– <a href="#Events-off">off</a></li> 336 <li data-name="trigger">– <a href="#Events-trigger">trigger</a></li> 337 <li data-name="once">– <a href="#Events-once">once</a></li> 338 <li data-name="listenTo">– <a href="#Events-listenTo">listenTo</a></li> 339 <li data-name="stopListening">– <a href="#Events-stopListening">stopListening</a></li> 340 <li data-name="listenToOnce">– <a href="#Events-listenToOnce">listenToOnce</a></li> 341 <li data-name="Catalog of Built-in Events">- <a href="#Events-catalog"><b>Catalog of Built-in Events</b></a></li> 342 </ul> 343 </div> 344 345 <div class="searchable_section"> 346 <a class="toc_title" href="#Model"> 347 Model 348 </a> 349 <ul class="toc_section"> 350 <li data-name="extend">– <a href="#Model-extend">extend</a></li> 351 <li data-name="preinitialize">– <a href="#Model-preinitialize">preinitialize</a></li> 352 <li data-name="constructor / initialize">– <a href="#Model-constructor">constructor / initialize</a></li> 353 <li data-name="get">– <a href="#Model-get">get</a></li> 354 <li data-name="set">– <a href="#Model-set">set</a></li> 355 <li data-name="escape">– <a href="#Model-escape">escape</a></li> 356 <li data-name="has">– <a href="#Model-has">has</a></li> 357 <li data-name="unset">– <a href="#Model-unset">unset</a></li> 358 <li data-name="clear">– <a href="#Model-clear">clear</a></li> 359 <li data-name="id">– <a href="#Model-id">id</a></li> 360 <li data-name="idAttribute">– <a href="#Model-idAttribute">idAttribute</a></li> 361 <li data-name="cid">– <a href="#Model-cid">cid</a></li> 362 <li data-name="attributes">– <a href="#Model-attributes">attributes</a></li> 363 <li data-name="changed">– <a href="#Model-changed">changed</a></li> 364 <li data-name="defaults">– <a href="#Model-defaults">defaults</a></li> 365 <li data-name="toJSON">– <a href="#Model-toJSON">toJSON</a></li> 366 <li data-name="sync">– <a href="#Model-sync">sync</a></li> 367 <li data-name="fetch">– <a href="#Model-fetch">fetch</a></li> 368 <li data-name="save">– <a href="#Model-save">save</a></li> 369 <li data-name="destroy">– <a href="#Model-destroy">destroy</a></li> 370 <li data-name="Underscore Methods">– <a href="#Model-Underscore-Methods"><b>Underscore Methods (9)</b></a></li> 371 <li data-name="validate">– <a href="#Model-validate">validate</a></li> 372 <li data-name="validationError">– <a href="#Model-validationError">validationError</a></li> 373 <li data-name="isValid">– <a href="#Model-isValid">isValid</a></li> 374 <li data-name="url">– <a href="#Model-url">url</a></li> 375 <li data-name="urlRoot">– <a href="#Model-urlRoot">urlRoot</a></li> 376 <li data-name="parse">– <a href="#Model-parse">parse</a></li> 377 <li data-name="clone">– <a href="#Model-clone">clone</a></li> 378 <li data-name="isNew">– <a href="#Model-isNew">isNew</a></li> 379 <li data-name="hasChanged">– <a href="#Model-hasChanged">hasChanged</a></li> 380 <li data-name="changedAttributes">– <a href="#Model-changedAttributes">changedAttributes</a></li> 381 <li data-name="previous">– <a href="#Model-previous">previous</a></li> 382 <li data-name="previousAttributes">– <a href="#Model-previousAttributes">previousAttributes</a></li> 383 </ul> 384 </div> 385 386 <div class="searchable_section"> 387 <a class="toc_title" href="#Collection"> 388 Collection 389 </a> 390 <ul class="toc_section"> 391 <li data-name="extend">– <a href="#Collection-extend">extend</a></li> 392 <li data-name="model">– <a href="#Collection-model">model</a></li> 393 <li data-name="modelId">– <a href="#Collection-modelId">modelId</a></li> 394 <li data-name="preinitialize" data-name="preinitialize">– <a href="#Collection-preinitialize">preinitialize</a></li> 395 <li data-name="constructor / initialize" data-name="constructor / initialize">– <a href="#Collection-constructor">constructor / initialize</a></li> 396 <li data-name="models">– <a href="#Collection-models">models</a></li> 397 <li data-name="toJSON">– <a href="#Collection-toJSON">toJSON</a></li> 398 <li data-name="sync">– <a href="#Collection-sync">sync</a></li> 399 <li data-name="Underscore Methods">– <a href="#Collection-Underscore-Methods"><b>Underscore Methods (46)</b></a></li> 400 <li data-name="add">– <a href="#Collection-add">add</a></li> 401 <li data-name="remove">– <a href="#Collection-remove">remove</a></li> 402 <li data-name="reset">– <a href="#Collection-reset">reset</a></li> 403 <li data-name="set">– <a href="#Collection-set">set</a></li> 404 <li data-name="get">– <a href="#Collection-get">get</a></li> 405 <li data-name="at">– <a href="#Collection-at">at</a></li> 406 <li data-name="push">– <a href="#Collection-push">push</a></li> 407 <li data-name="pop">– <a href="#Collection-pop">pop</a></li> 408 <li data-name="unshift">– <a href="#Collection-unshift">unshift</a></li> 409 <li data-name="shift">– <a href="#Collection-shift">shift</a></li> 410 <li data-name="slice">– <a href="#Collection-slice">slice</a></li> 411 <li data-name="length">– <a href="#Collection-length">length</a></li> 412 <li data-name="comparator">– <a href="#Collection-comparator">comparator</a></li> 413 <li data-name="sort">– <a href="#Collection-sort">sort</a></li> 414 <li data-name="pluck">– <a href="#Collection-pluck">pluck</a></li> 415 <li data-name="where">– <a href="#Collection-where">where</a></li> 416 <li data-name="findWhere">– <a href="#Collection-findWhere">findWhere</a></li> 417 <li data-name="url">– <a href="#Collection-url">url</a></li> 418 <li data-name="parse">– <a href="#Collection-parse">parse</a></li> 419 <li data-name="clone">– <a href="#Collection-clone">clone</a></li> 420 <li data-name="fetch">– <a href="#Collection-fetch">fetch</a></li> 421 <li data-name="create">– <a href="#Collection-create">create</a></li> 422 <li data-name="sync">– <a href="#Collection-mixin">mixin</a></li> 423 </ul> 424 </div> 425 426 <div class="searchable_section"> 427 <a class="toc_title" href="#Router"> 428 Router 429 </a> 430 <ul class="toc_section"> 431 <li data-name="extend">– <a href="#Router-extend">extend</a></li> 432 <li data-name="routes">– <a href="#Router-routes">routes</a></li> 433 <li data-name="preinitialize">– <a href="#Router-preinitialize">preinitialize</a></li> 434 <li data-name="constructor / initialize">– <a href="#Router-constructor">constructor / initialize</a></li> 435 <li data-name="route">– <a href="#Router-route">route</a></li> 436 <li data-name="navigate">– <a href="#Router-navigate">navigate</a></li> 437 <li data-name="execute">– <a href="#Router-execute">execute</a></li> 438 </ul> 439 </div> 440 441 <div class="searchable_section"> 442 <a class="toc_title" href="#History"> 443 History 444 </a> 445 <ul class="toc_section"> 446 <li data-name="start">– <a href="#History-start">start</a></li> 447 </ul> 448 </div> 449 450 <div class="searchable_section"> 451 <a class="toc_title" href="#Sync"> 452 Sync 453 </a> 454 <ul class="toc_section"> 455 <li data-name="Backbone.sync">– <a href="#Sync">Backbone.sync</a></li> 456 <li data-name="Backbone.ajax">– <a href="#Sync-ajax">Backbone.ajax</a></li> 457 <li data-name="Backbone.emulateHTTP">– <a href="#Sync-emulateHTTP">Backbone.emulateHTTP</a></li> 458 <li data-name="Backbone.emulateJSON">– <a href="#Sync-emulateJSON">Backbone.emulateJSON</a></li> 459 </ul> 460 </div> 461 462 <div class="searchable_section"> 463 <a class="toc_title" href="#View"> 464 View 465 </a> 466 <ul class="toc_section"> 467 <li data-name="extend">– <a href="#View-extend">extend</a></li> 468 <li data-name="preinitialize">– <a href="#View-preinitialize">preinitialize</a></li> 469 <li data-name="constructor / initialize">– <a href="#View-constructor">constructor / initialize</a></li> 470 <li data-name="el">– <a href="#View-el">el</a></li> 471 <li data-name="$el">– <a href="#View-$el">$el</a></li> 472 <li data-name="setElement">– <a href="#View-setElement">setElement</a></li> 473 <li data-name="attributes">– <a href="#View-attributes">attributes</a></li> 474 <li data-name="$ (jQuery)">– <a href="#View-dollar">$ (jQuery)</a></li> 475 <li data-name="template">– <a href="#View-template">template</a></li> 476 <li data-name="render">– <a href="#View-render">render</a></li> 477 <li data-name="remove">– <a href="#View-remove">remove</a></li> 478 <li data-name="events">– <a href="#View-events">events</a></li> 479 <li data-name="delegateEvents">– <a href="#View-delegateEvents">delegateEvents</a></li> 480 <li data-name="undelegateEvents">– <a href="#View-undelegateEvents">undelegateEvents</a></li> 481 </ul> 482 </div> 483 484 <div class="searchable_section"> 485 <a class="toc_title" href="#Utility"> 486 Utility 487 </a> 488 <ul class="toc_section"> 489 <li data-name="Backbone.noConflict">– <a href="#Utility-Backbone-noConflict">Backbone.noConflict</a></li> 490 <li data-name="Backbone.$">– <a href="#Utility-Backbone-$">Backbone.$</a></li> 491 </ul> 492 </div> 493 494 <div class="searchable_section"> 495 <a class="toc_title" href="#faq"> 496 F.A.Q. 497 </a> 498 <ul class="toc_section"> 499 <li data-name="Why Backbone?">– <a href="#FAQ-why-backbone">Why Backbone?</a></li> 500 <li data-name="More Than One Way To Do It">– <a href="#FAQ-tim-toady">More Than One Way To Do It</a></li> 501 <li data-name="Nested Models and Collections">– <a href="#FAQ-nested">Nested Models & Collections</a></li> 502 <li data-name="Loading Bootstrapped Models">– <a href="#FAQ-bootstrap">Loading Bootstrapped Models</a></li> 503 <li data-name="Extending Backbone">– <a href="#FAQ-extending">Extending Backbone</a></li> 504 <li data-name="Traditional MVC">– <a href="#FAQ-mvc">Traditional MVC</a></li> 505 <li data-name="Binding this">– <a href="#FAQ-this">Binding "this"</a></li> 506 <li data-name="Working with Rails">– <a href="#FAQ-rails">Working with Rails</a></li> 507 </ul> 508 </div> 509 510 <div class="searchable_section"> 511 <a class="toc_title" href="#examples"> 512 Examples 513 </a> 514 <ul class="toc_section"> 515 <li data-name="Todos">– <a href="#examples-todos">Todos</a></li> 516 <li data-name="DocumentCloud">– <a href="#examples-documentcloud">DocumentCloud</a></li> 517 <li data-name="USA Today">– <a href="#examples-usa-today">USA Today</a></li> 518 <li data-name="Rdio">– <a href="#examples-rdio">Rdio</a></li> 519 <li data-name="Hulu">– <a href="#examples-hulu">Hulu</a></li> 520 <li data-name="Quartz">– <a href="#examples-quartz">Quartz</a></li> 521 <li data-name="Earth">– <a href="#examples-earth">Earth</a></li> 522 <li data-name="Vox">– <a href="#examples-vox">Vox</a></li> 523 <li data-name="Gawker Media">– <a href="#examples-gawker">Gawker Media</a></li> 524 <li data-name="Flow">– <a href="#examples-flow">Flow</a></li> 525 <li data-name="Gilt Groupe">– <a href="#examples-gilt">Gilt Groupe</a></li> 526 <li data-name="Enigma">– <a href="#examples-enigma">Enigma</a></li> 527 <li data-name="NewsBlur">– <a href="#examples-newsblur">NewsBlur</a></li> 528 <li data-name="WordPress.com">– <a href="#examples-wordpress">WordPress.com</a></li> 529 <li data-name="Foursquare">– <a href="#examples-foursquare">Foursquare</a></li> 530 <li data-name="Bitbucket">– <a href="#examples-bitbucket">Bitbucket</a></li> 531 <li data-name="Disqus">– <a href="#examples-disqus">Disqus</a></li> 532 <li data-name="Delicious">– <a href="#examples-delicious">Delicious</a></li> 533 <li data-name="Khan Academy">– <a href="#examples-khan-academy">Khan Academy</a></li> 534 <li data-name="IRCCloud">– <a href="#examples-irccloud">IRCCloud</a></li> 535 <li data-name="Pitchfork">– <a href="#examples-pitchfork">Pitchfork</a></li> 536 <li data-name="Spin">– <a href="#examples-spin">Spin</a></li> 537 <li data-name="ZocDoc">– <a href="#examples-zocdoc">ZocDoc</a></li> 538 <li data-name="Walmart Mobile">– <a href="#examples-walmart">Walmart Mobile</a></li> 539 <li data-name="Groupon Now!">– <a href="#examples-groupon">Groupon Now!</a></li> 540 <li data-name="Basecamp">– <a href="#examples-basecamp">Basecamp</a></li> 541 <li data-name="Slavery Footprint">– <a href="#examples-slavery-footprint">Slavery Footprint</a></li> 542 <li data-name="Stripe">– <a href="#examples-stripe">Stripe</a></li> 543 <li data-name="Airbnb">– <a href="#examples-airbnb">Airbnb</a></li> 544 <li data-name="SoundCloud Mobile">– <a href="#examples-soundcloud">SoundCloud Mobile</a></li> 545 <li data-name="Art.sy">- <a href="#examples-artsy">Art.sy</a></li> 546 <li data-name="Pandora">– <a href="#examples-pandora">Pandora</a></li> 547 <li data-name="Inkling">– <a href="#examples-inkling">Inkling</a></li> 548 <li data-name="Code School">– <a href="#examples-code-school">Code School</a></li> 549 <li data-name="CloudApp">– <a href="#examples-cloudapp">CloudApp</a></li> 550 <li data-name="SeatGeek">– <a href="#examples-seatgeek">SeatGeek</a></li> 551 <li data-name="Easel">– <a href="#examples-easel">Easel</a></li> 552 <li data-name="Jolicloud">- <a href="#examples-jolicloud">Jolicloud</a></li> 553 <li data-name="Salon.io">– <a href="#examples-salon">Salon.io</a></li> 554 <li data-name="TileMill">– <a href="#examples-tilemill">TileMill</a></li> 555 <li data-name="Blossom">– <a href="#examples-blossom">Blossom</a></li> 556 <li data-name="Trello">– <a href="#examples-trello">Trello</a></li> 557 <li data-name="Tzigla">– <a href="#examples-tzigla">Tzigla</a></li> 558 </ul> 559 </div> 560 561 <div class="searchable_section"> 562 <a class="toc_title" href="#changelog"> 563 Change Log 564 </a> 565 </div> 566 567 </div> 568 569 <div class="container"> 570 571 <p> 572 <img id="logo" src="docs/images/backbone.png" alt="Backbone.js" /> 573 </p> 574 575 <p> 576 Backbone.js gives structure to web applications 577 by providing <b>models</b> with key-value binding and custom events, 578 <b>collections</b> with a rich API of enumerable functions, 579 <b>views</b> with declarative event handling, and connects it all to your 580 existing API over a RESTful JSON interface. 581 </p> 582 583 <p> 584 The project is <a href="http://github.com/jashkenas/backbone/">hosted on GitHub</a>, 585 and the <a href="docs/backbone.html">annotated source code</a> is available, 586 as well as an online <a href="test/">test suite</a>, 587 an <a href="examples/todos/index.html">example application</a>, 588 a <a href="https://github.com/jashkenas/backbone/wiki/Tutorials%2C-blog-posts-and-example-sites">list of tutorials</a> 589 and a <a href="#examples">long list of real-world projects</a> that use Backbone. 590 Backbone is available for use under the <a href="http://github.com/jashkenas/backbone/blob/master/LICENSE">MIT software license</a>. 591 </p> 592 593 <p> 594 You can report bugs and discuss features on the 595 <a href="http://github.com/jashkenas/backbone/issues">GitHub issues page</a>, 596 or add pages to the <a href="https://github.com/jashkenas/backbone/wiki">wiki</a>. 597 </p> 598 599 <p> 600 <i> 601 Backbone is an open-source component of 602 <a href="http://documentcloud.org/">DocumentCloud</a>. 603 </i> 604 </p> 605 606 <h2 id="downloads"> 607 Downloads & Dependencies 608 <span style="padding-left: 7px; font-size:11px; font-weight: normal;" class="interface">(Right-click, and use "Save As")</span> 609 </h2> 610 611 <table> 612 <tr> 613 <td><a class="punch" href="backbone.js">Development Version (1.4.0)</a></td> 614 <td class="text"><i>72kb, Full source, tons of comments</i></td> 615 </tr> 616 <tr> 617 <td><a class="punch" href="backbone-min.js">Production Version (1.4.0)</a></td> 618 <td class="text" style="line-height: 16px;"> 619 <i>7.9kb, Packed and gzipped</i><br /> 620 <small>(<a href="backbone-min.map">Source Map</a>)</small> 621 </td> 622 </tr> 623 <tr> 624 <td><a class="punch" href="https://raw.github.com/jashkenas/backbone/master/backbone.js">Edge Version (master)</a></td> 625 <td> 626 <i>Unreleased, use at your own risk</i> 627 </td> 628 </tr> 629 </table> 630 631 <p> 632 Backbone's only hard dependency is 633 <a href="http://underscorejs.org/">Underscore.js</a> <small>( >= 1.8.3)</small>. 634 For RESTful persistence and DOM manipulation with <a href="#View">Backbone.View</a>, 635 include <b><a href="https://jquery.com/">jQuery</a></b> ( >= 1.11.0). 636 <i>(Mimics of the Underscore and jQuery APIs, such as 637 <a href="https://lodash.com/">Lodash</a> and 638 <a href="http://zeptojs.com/">Zepto</a>, will 639 also tend to work, with varying degrees of compatibility.)</i> 640 </p> 641 <h2 id="Getting-started">Getting Started</h2> 642 643 <p> 644 When working on a web application that involves a lot of JavaScript, one 645 of the first things you learn is to stop tying your data to the DOM. It's all 646 too easy to create JavaScript applications that end up as tangled piles of 647 jQuery selectors and callbacks, all trying frantically to keep data in 648 sync between the HTML UI, your JavaScript logic, and the database on your 649 server. For rich client-side applications, a more structured approach 650 is often helpful. 651 </p> 652 653 <p> 654 With Backbone, you represent your data as 655 <a href="#Model">Models</a>, which can be created, validated, destroyed, 656 and saved to the server. Whenever a UI action causes an attribute of 657 a model to change, the model triggers a <i>"change"</i> event; all 658 the <a href="#View">Views</a> that display the model's state can be notified of the 659 change, so that they are able to respond accordingly, re-rendering themselves with 660 the new information. In a finished Backbone app, you don't have to write the glue 661 code that looks into the DOM to find an element with a specific <i>id</i>, 662 and update the HTML manually 663 — when the model changes, the views simply update themselves. 664 </p> 665 666 <p> 667 Philosophically, Backbone is an attempt to discover the minimal set 668 of data-structuring (models and collections) and user interface (views 669 and URLs) primitives that are generally useful when building web applications with 670 JavaScript. In an ecosystem where overarching, decides-everything-for-you 671 frameworks are commonplace, and many libraries require your site to be 672 reorganized to suit their look, feel, and default behavior — Backbone should 673 continue to be a tool that gives you the <i>freedom</i> to design the full 674 experience of your web application. 675 </p> 676 677 <p> 678 If you're new here, and aren't yet quite sure what Backbone is for, start by 679 browsing the <a href="#examples">list of Backbone-based projects</a>. 680 </p> 681 682 <p> 683 Many of the code examples in this documentation are runnable, because 684 Backbone is included on this page. 685 Click the <i>play</i> button to execute them. 686 </p> 687 688 <h2 id="Model-View-separation">Models and Views</h2> 689 690 <img class="figure" src="docs/images/intro-model-view.svg" alt="Model-View Separation."> 691 692 <p> 693 The single most important thing that Backbone can help you with is keeping 694 your business logic separate from your user interface. When the two are 695 entangled, change is hard; when logic doesn't depend on UI, your 696 interface becomes easier to work with. 697 </p> 698 699 <div class="columns"> 700 <div class="col-50"> 701 <b>Model</b> 702 <ul> 703 <li>Orchestrates data and business logic.</li> 704 <li>Loads and saves data from the server.</li> 705 <li>Emits events when data changes.</li> 706 </ul> 707 </div> 708 <div class="col-50"> 709 <b>View</b> 710 <ul> 711 <li>Listens for changes and renders UI.</li> 712 <li>Handles user input and interactivity.</li> 713 <li>Sends captured input to the model.</li> 714 </ul> 715 </div> 716 </div> 717 718 <p> 719 A <b>Model</b> manages an internal table of data attributes, and 720 triggers <tt>"change"</tt> events when any of its data is modified. 721 Models handle syncing data with a persistence layer — usually a REST API 722 with a backing database. Design your models as the atomic reusable objects 723 containing all of the helpful functions for manipulating their particular 724 bit of data. Models should be able to be passed around throughout your app, 725 and used anywhere that bit of data is needed. 726 </p> 727 728 <p> 729 A <b>View</b> is an atomic chunk of user interface. It often renders the 730 data from a specific model, or number of models — but views can 731 also be data-less chunks of UI that stand alone. 732 Models should be generally unaware of views. Instead, views listen to 733 the model <tt>"change"</tt> events, and react or re-render themselves 734 appropriately. 735 </p> 736 737 <h2 id="Model-Collections">Collections</h2> 738 739 <img class="figure" src="docs/images/intro-collections.svg" alt="Model Collections."> 740 741 <p> 742 A <b>Collection</b> helps you deal with a group of related models, handling 743 the loading and saving of new models to the server and providing helper 744 functions for performing aggregations or computations against a list of models. 745 Aside from their own events, collections also proxy through all of the 746 events that occur to models within them, allowing you to listen in one place 747 for any change that might happen to any model in the collection. 748 </p> 749 750 <h2 id="API-integration">API Integration</h2> 751 752 <p> 753 Backbone is pre-configured to sync with a RESTful API. Simply create a 754 new Collection with the <tt>url</tt> of your resource endpoint: 755 </p> 756 757<pre> 758var Books = Backbone.Collection.extend({ 759 url: '/books' 760}); 761</pre> 762 763 <p> 764 The <b>Collection</b> and <b>Model</b> components together form a direct 765 mapping of REST resources using the following methods: 766 </p> 767 768<pre> 769GET /books/ .... collection.fetch(); 770POST /books/ .... collection.create(); 771GET /books/1 ... model.fetch(); 772PUT /books/1 ... model.save(); 773DEL /books/1 ... model.destroy(); 774</pre> 775 776 <p> 777 When fetching raw JSON data from an API, a <b>Collection</b> will 778 automatically populate itself with data formatted as an array, while 779 a <b>Model</b> will automatically populate itself with data formatted 780 as an object: 781 </p> 782 783<pre> 784[{"id": 1}] ..... populates a Collection with one model. 785{"id": 1} ....... populates a Model with one attribute. 786</pre> 787 788 <p> 789 However, it's fairly common to encounter APIs that return data in a 790 different format than what Backbone expects. For example, consider 791 fetching a <b>Collection</b> from an API that returns the real data 792 array wrapped in metadata: 793 </p> 794 795<pre> 796{ 797 "page": 1, 798 "limit": 10, 799 "total": 2, 800 "books": [ 801 {"id": 1, "title": "Pride and Prejudice"}, 802 {"id": 4, "title": "The Great Gatsby"} 803 ] 804} 805</pre> 806 807 <p> 808 In the above example data, a <b>Collection</b> should populate using the 809 <tt>"books"</tt> array rather than the root object structure. This 810 difference is easily reconciled using a <tt>parse</tt> method that 811 returns (or transforms) the desired portion of API data: 812 </p> 813 814<pre> 815var Books = Backbone.Collection.extend({ 816 url: '/books', 817 parse: function(data) { 818 return data.books; 819 } 820}); 821</pre> 822 823 <h2 id="View-rendering">View Rendering</h2> 824 825 <img class="figure" src="docs/images/intro-views.svg" alt="View rendering."> 826 827 <p> 828 Each <b>View</b> manages the rendering and user interaction within its own 829 DOM element. If you're strict about not allowing views to reach outside 830 of themselves, it helps keep your interface flexible — allowing 831 views to be rendered in isolation in any place where they might be needed. 832 </p> 833 834 <p> 835 Backbone remains unopinionated about the process used to render <b>View</b> 836 objects and their subviews into UI: you define how your models get translated 837 into HTML (or SVG, or Canvas, or something even more exotic). 838 It could be as prosaic as a simple 839 <a href="http://underscorejs.org/#template">Underscore template</a>, or as fancy as the 840 <a href="http://facebook.github.io/react/docs/tutorial.html">React virtual DOM</a>. 841 Some basic approaches to rendering views can be found 842 in the <a href="https://github.com/jashkenas/backbone/wiki/Backbone%2C-The-Primer">Backbone primer</a>. 843 </p> 844 845 <h2 id="Routing">Routing with URLs</h2> 846 847 <img class="figure" src="docs/images/intro-routing.svg" alt="Routing"> 848 849 <p> 850 In rich web applications, we still want to provide linkable, 851 bookmarkable, and shareable URLs to meaningful locations within an app. 852 Use the <b>Router</b> to update the browser URL whenever the user 853 reaches a new "place" in your app that they might want to bookmark or share. 854 Conversely, the <b>Router</b> detects changes to the URL — say, 855 pressing the "Back" button — and can tell your application exactly where you 856 are now. 857 </p> 858 859 <h2 id="Events">Backbone.Events</h2> 860 861 <p> 862 <b>Events</b> is a module that can be mixed in to any object, giving the 863 object the ability to bind and trigger custom named events. Events do not 864 have to be declared before they are bound, and may take passed arguments. 865 For example: 866 </p> 867 868<pre class="runnable"> 869var object = {}; 870 871_.extend(object, Backbone.Events); 872 873object.on("alert", function(msg) { 874 alert("Triggered " + msg); 875}); 876 877object.trigger("alert", "an event"); 878</pre> 879 880 <p> 881 For example, to make a handy event dispatcher that can coordinate events 882 among different areas of your application: <tt>var dispatcher = _.clone(Backbone.Events)</tt> 883 </p> 884 885 <p id="Events-on"> 886 <b class="header">on</b><code>object.on(event, callback, [context])</code><span class="alias">Alias: bind</span> 887 <br /> 888 Bind a <b>callback</b> function to an object. The callback will be invoked 889 whenever the <b>event</b> is fired. 890 If you have a large number of different events on a page, the convention is to use colons to 891 namespace them: <tt>"poll:start"</tt>, or <tt>"change:selection"</tt>. 892 The event string may also be a space-delimited list of several events... 893 </p> 894 895<pre> 896book.on("change:title change:author", ...); 897</pre> 898 899 <p> 900 Callbacks bound to the special 901 <tt>"all"</tt> event will be triggered when any event occurs, and are passed 902 the name of the event as the first argument. For example, to proxy all events 903 from one object to another: 904 </p> 905 906<pre> 907proxy.on("all", function(eventName) { 908 object.trigger(eventName); 909}); 910</pre> 911 912 <p> 913 All Backbone event methods also support an event map syntax, as an alternative 914 to positional arguments: 915 </p> 916 917<pre> 918book.on({ 919 "change:author": authorPane.update, 920 "change:title change:subtitle": titleView.update, 921 "destroy": bookView.remove 922}); 923</pre> 924 925 <p> 926 To supply a <b>context</b> value for <tt>this</tt> when the callback is invoked, 927 pass the optional last argument: <tt>model.on('change', this.render, this)</tt> or 928 <tt>model.on({change: this.render}, this)</tt>. 929 </p> 930 931 <p id="Events-off"> 932 <b class="header">off</b><code>object.off([event], [callback], [context])</code><span class="alias">Alias: unbind</span> 933 <br /> 934 Remove a previously-bound <b>callback</b> function from an object. If no 935 <b>context</b> is specified, all of the versions of the callback with 936 different contexts will be removed. If no 937 callback is specified, all callbacks for the <b>event</b> will be 938 removed. If no event is specified, callbacks for <i>all</i> events 939 will be removed. 940 </p> 941 942<pre> 943// Removes just the `onChange` callback. 944object.off("change", onChange); 945 946// Removes all "change" callbacks. 947object.off("change"); 948 949// Removes the `onChange` callback for all events. 950object.off(null, onChange); 951 952// Removes all callbacks for `context` for all events. 953object.off(null, null, context); 954 955// Removes all callbacks on `object`. 956object.off(); 957</pre> 958 959 <p> 960 Note that calling <tt>model.off()</tt>, for example, will indeed remove <i>all</i> events 961 on the model — including events that Backbone uses for internal bookkeeping. 962 </p> 963 964 <p id="Events-trigger"> 965 <b class="header">trigger</b><code>object.trigger(event, [*args])</code> 966 <br /> 967 Trigger callbacks for the given <b>event</b>, or space-delimited list of events. 968 Subsequent arguments to <b>trigger</b> will be passed along to the 969 event callbacks. 970 </p> 971 972 <p id="Events-once"> 973 <b class="header">once</b><code>object.once(event, callback, [context])</code> 974 <br /> 975 Just like <a href="#Events-on">on</a>, but causes the bound callback to fire 976 only once before being removed. Handy for saying "the next time that X happens, do this". 977 When multiple events are passed in using the space separated syntax, the event will fire once 978 for every event you passed in, not once for a combination of all events 979 </p> 980 981 <p id="Events-listenTo"> 982 <b class="header">listenTo</b><code>object.listenTo(other, event, callback)</code> 983 <br /> 984 Tell an <b>object</b> to listen to a particular event on an <b>other</b> 985 object. The advantage of using this form, instead of <tt>other.on(event, 986 callback, object)</tt>, is that <b>listenTo</b> allows the <b>object</b> 987 to keep track of the events, and they can be removed all at once later 988 on. The <b>callback</b> will always be called with <b>object</b> as 989 context. 990 </p> 991 992<pre> 993view.listenTo(model, 'change', view.render); 994</pre> 995 996 <p id="Events-stopListening"> 997 <b class="header">stopListening</b><code>object.stopListening([other], [event], [callback])</code> 998 <br /> 999 Tell an <b>object</b> to stop listening to events. Either call 1000 <b>stopListening</b> with no arguments to have the <b>object</b> remove 1001 all of its <a href="#Events-listenTo">registered</a> callbacks ... or be more 1002 precise by telling it to remove just the events it's listening to on a 1003 specific object, or a specific event, or just a specific callback. 1004 </p> 1005 1006<pre> 1007view.stopListening(); 1008 1009view.stopListening(model); 1010</pre> 1011 1012 <p id="Events-listenToOnce"> 1013 <b class="header">listenToOnce</b><code>object.listenToOnce(other, event, callback)</code> 1014 <br /> 1015 Just like <a href="#Events-listenTo">listenTo</a>, but causes the bound 1016 callback to fire only once before being removed. 1017 </p> 1018 1019 <p id="Events-catalog"> 1020 <b class="header">Catalog of Events</b> 1021 <br /> 1022 Here's the complete list of built-in Backbone events, with arguments. 1023 You're also free to trigger your own events on Models, Collections and 1024 Views as you see fit. The <tt>Backbone</tt> object itself mixes in <tt>Events</tt>, 1025 and can be used to emit any global events that your application needs. 1026 </p> 1027 1028 <ul class="small"> 1029 <li><b>"add"</b> (model, collection, options) — when a model is added to a collection.</li> 1030 <li><b>"remove"</b> (model, collection, options) — when a model is removed from a collection.</li> 1031 <li><b>"update"</b> (collection, options) — single event triggered after any number of models have been added, removed or changed in a collection.</li> 1032 <li><b>"reset"</b> (collection, options) — when the collection's entire contents have been <a href="#Collection-reset">reset</a>.</li> 1033 <li><b>"sort"</b> (collection, options) — when the collection has been re-sorted.</li> 1034 <li><b>"change"</b> (model, options) — when a model's attributes have changed.</li> 1035 <li><b>"change:[attribute]"</b> (model, value, options) — when a specific attribute has been updated.</li> 1036 <li><b>"destroy"</b> (model, collection, options) — when a model is <a href="#Model-destroy">destroyed</a>.</li> 1037 <li><b>"request"</b> (model_or_collection, xhr, options) — when a model or collection has started a request to the server.</li> 1038 <li><b>"sync"</b> (model_or_collection, response, options) — when a model or collection has been successfully synced with the server.</li> 1039 <li><b>"error"</b> (model_or_collection, xhr, options) — when a model's or collection's request to the server has failed.</li> 1040 <li><b>"invalid"</b> (model, error, options) — when a model's <a href="#Model-validate">validation</a> fails on the client.</li> 1041 <li><b>"route:[name]"</b> (params) — Fired by the router when a specific route is matched.</li> 1042 <li><b>"route"</b> (route, params) — Fired by the router when <i>any</i> route has been matched.</li> 1043 <li><b>"route"</b> (router, route, params) — Fired by history when <i>any</i> route has been matched.</li> 1044 <li><b>"all"</b> — this special event fires for <i>any</i> triggered event, passing the event name as the first argument followed by all trigger arguments.</li> 1045 </ul> 1046 1047 <p> 1048 Generally speaking, when calling a function that emits an event 1049 (<tt>model.set</tt>, <tt>collection.add</tt>, and so on...), 1050 if you'd like to prevent the event from being triggered, you may pass 1051 <tt>{silent: true}</tt> as an option. Note that this is <i>rarely</i>, 1052 perhaps even never, a good idea. Passing through a specific flag 1053 in the options for your event callback to look at, and choose to ignore, 1054 will usually work out better. 1055 </p> 1056 1057 <h2 id="Model">Backbone.Model</h2> 1058 1059 <p> 1060 <b>Models</b> are the heart of any JavaScript application, containing 1061 the interactive data as well as a large part of the logic surrounding it: 1062 conversions, validations, computed properties, and access control. You 1063 extend <b>Backbone.Model</b> with your domain-specific methods, and 1064 <b>Model</b> provides a basic set of functionality for managing changes. 1065 </p> 1066 1067 <p> 1068 The following is a contrived example, but it demonstrates defining a model 1069 with a custom method, setting an attribute, and firing an event keyed 1070 to changes in that specific attribute. 1071 After running this code once, <tt>sidebar</tt> will be 1072 available in your browser's console, so you can play around with it. 1073 </p> 1074 1075<pre class="runnable"> 1076var Sidebar = Backbone.Model.extend({ 1077 promptColor: function() { 1078 var cssColor = prompt("Please enter a CSS color:"); 1079 this.set({color: cssColor}); 1080 } 1081}); 1082 1083window.sidebar = new Sidebar; 1084 1085sidebar.on('change:color', function(model, color) { 1086 $('#sidebar').css({background: color}); 1087}); 1088 1089sidebar.set({color: 'white'}); 1090 1091sidebar.promptColor(); 1092</pre> 1093 1094 <p id="Model-extend"> 1095 <b class="header">extend</b><code>Backbone.Model.extend(properties, [classProperties])</code> 1096 <br /> 1097 To create a <b>Model</b> class of your own, you extend <b>Backbone.Model</b> 1098 and provide instance <b>properties</b>, as well as optional 1099 <b>classProperties</b> to be attached directly to the constructor function. 1100 </p> 1101 1102 <p> 1103 <b>extend</b> correctly sets up the prototype chain, so subclasses created 1104 with <b>extend</b> can be further extended and subclassed as far as you like. 1105 </p> 1106 1107<pre> 1108var Note = Backbone.Model.extend({ 1109 1110 initialize: function() { ... }, 1111 1112 author: function() { ... }, 1113 1114 coordinates: function() { ... }, 1115 1116 allowedToEdit: function(account) { 1117 return true; 1118 } 1119 1120}); 1121 1122var PrivateNote = Note.extend({ 1123 1124 allowedToEdit: function(account) { 1125 return account.owns(this); 1126 } 1127 1128}); 1129</pre> 1130 1131 <p class="warning"> 1132 Brief aside on <tt>super</tt>: JavaScript does not provide 1133 a simple way to call super — the function of the same name defined 1134 higher on the prototype chain. If you override a core function like 1135 <tt>set</tt>, or <tt>save</tt>, and you want to invoke the 1136 parent object's implementation, you'll have to explicitly call it, along these lines: 1137 </p> 1138 1139<pre> 1140var Note = Backbone.Model.extend({ 1141 set: function(attributes, options) { 1142 Backbone.Model.prototype.set.apply(this, arguments); 1143 ... 1144 } 1145}); 1146</pre> 1147 1148 <p id="Model-preinitialize"> 1149 <b class="header">preinitialize</b><code>new Model([attributes], [options])</code> 1150 <br /> 1151 For use with models as ES classes. If you define a <b>preinitialize</b> 1152 method, it will be invoked when the Model is first created, before any 1153 instantiation logic is run for the Model. 1154 </p> 1155 1156<pre> 1157class Country extends Backbone.Model { 1158 preinitialize({countryCode}) { 1159 this.name = COUNTRY_NAMES[countryCode]; 1160 } 1161 1162 initialize() { ... } 1163} 1164</pre> 1165 1166 <p id="Model-constructor"> 1167 <b class="header">constructor / initialize</b><code>new Model([attributes], [options])</code> 1168 <br /> 1169 When creating an instance of a model, you can pass in the initial values 1170 of the <b>attributes</b>, which will be <a href="#Model-set">set</a> on the 1171 model. If you define an <b>initialize</b> function, it will be invoked when 1172 the model is created. 1173 </p> 1174 1175<pre> 1176new Book({ 1177 title: "One Thousand and One Nights", 1178 author: "Scheherazade" 1179}); 1180</pre> 1181 1182 <p> 1183 In rare cases, if you're looking to get fancy, 1184 you may want to override <b>constructor</b>, which allows 1185 you to replace the actual constructor function for your model. 1186 </p> 1187 1188<pre> 1189var Library = Backbone.Model.extend({ 1190 constructor: function() { 1191 this.books = new Books(); 1192 Backbone.Model.apply(this, arguments); 1193 }, 1194 parse: function(data, options) { 1195 this.books.reset(data.books); 1196 return data.library; 1197 } 1198}); 1199</pre> 1200 1201 <p> 1202 If you pass a <tt>{collection: ...}</tt> as the <b>options</b>, the model 1203 gains a <tt>collection</tt> property that will be used to indicate which 1204 collection the model belongs to, and is used to help compute the model's 1205 <a href="#Model-url">url</a>. The <tt>model.collection</tt> property is 1206 normally created automatically when you first add a model to a collection. 1207 Note that the reverse is not true, as passing this option to the constructor 1208 will not automatically add the model to the collection. Useful, sometimes. 1209 </p> 1210 1211 <p> 1212 If <tt>{parse: true}</tt> is passed as an <b>option</b>, the <b>attributes</b> 1213 will first be converted by <a href="#Model-parse">parse</a> before being 1214 <a href="#Model-set">set</a> on the model. 1215 </p> 1216 1217 <p id="Model-get"> 1218 <b class="header">get</b><code>model.get(attribute)</code> 1219 <br /> 1220 Get the current value of an attribute from the model. For example: 1221 <tt>note.get("title")</tt> 1222 </p> 1223 1224 <p id="Model-set"> 1225 <b class="header">set</b><code>model.set(attributes, [options])</code> 1226 <br /> 1227 Set a hash of attributes (one or many) on the model. If any of the attributes 1228 change the model's state, a <tt>"change"</tt> event will be triggered on the model. 1229 Change events for specific attributes are also triggered, and you can bind 1230 to those as well, for example: <tt>change:title</tt>, and <tt>change:content</tt>. 1231 You may also pass individual keys and values. 1232 </p> 1233 1234<pre> 1235note.set({title: "March 20", content: "In his eyes she eclipses..."}); 1236 1237book.set("title", "A Scandal in Bohemia"); 1238</pre> 1239 1240 <p id="Model-escape"> 1241 <b class="header">escape</b><code>model.escape(attribute)</code> 1242 <br /> 1243 Similar to <a href="#Model-get">get</a>, but returns the HTML-escaped version 1244 of a model's attribute. If you're interpolating data from the model into 1245 HTML, using <b>escape</b> to retrieve attributes will prevent 1246 <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS</a> attacks. 1247 </p> 1248 1249<pre class="runnable"> 1250var hacker = new Backbone.Model({ 1251 name: "<script>alert('xss')</script>" 1252}); 1253 1254alert(hacker.escape('name')); 1255</pre> 1256 1257 <p id="Model-has"> 1258 <b class="header">has</b><code>model.has(attribute)</code> 1259 <br /> 1260 Returns <tt>true</tt> if the attribute is set to a non-null or non-undefined 1261 value. 1262 </p> 1263 1264<pre> 1265if (note.has("title")) { 1266 ... 1267} 1268</pre> 1269 1270 <p id="Model-unset"> 1271 <b class="header">unset</b><code>model.unset(attribute, [options])</code> 1272 <br /> 1273 Remove an attribute by deleting it from the internal attributes hash. 1274 Fires a <tt>"change"</tt> event unless <tt>silent</tt> is passed as an option. 1275 </p> 1276 1277 <p id="Model-clear"> 1278 <b class="header">clear</b><code>model.clear([options])</code> 1279 <br /> 1280 Removes all attributes from the model, including the <tt>id</tt> attribute. Fires a <tt>"change"</tt> event unless 1281 <tt>silent</tt> is passed as an option. 1282 </p> 1283 1284 <p id="Model-id"> 1285 <b class="header">id</b><code>model.id</code> 1286 <br /> 1287 A special property of models, the <b>id</b> is an arbitrary string 1288 (integer id or UUID). If you set the <b>id</b> in the 1289 attributes hash, it will be copied onto the model as a direct property. 1290 <code>model.id</code> should not be manipulated directly, 1291 it should be modified only via <code>model.set('id', …)</code>. 1292 Models can be retrieved by id from collections, and the id is used to generate 1293 model URLs by default. 1294 </p> 1295 1296 <p id="Model-idAttribute"> 1297 <b class="header">idAttribute</b><code>model.idAttribute</code> 1298 <br /> 1299 A model's unique identifier is stored under the <tt>id</tt> attribute. 1300 If you're directly communicating with a backend (CouchDB, MongoDB) that uses 1301 a different unique key, you may set a Model's <tt>idAttribute</tt> to 1302 transparently map from that key to <tt>id</tt>. 1303 1304<pre class="runnable"> 1305var Meal = Backbone.Model.extend({ 1306 idAttribute: "_id" 1307}); 1308 1309var cake = new Meal({ _id: 1, name: "Cake" }); 1310alert("Cake id: " + cake.id); 1311</pre> 1312 </p> 1313 1314 <p id="Model-cid"> 1315 <b class="header">cid</b><code>model.cid</code> 1316 <br /> 1317 A special property of models, the <b>cid</b> or client id is a unique identifier 1318 automatically assigned to all models when they're first created. Client ids 1319 are handy when the model has not yet been saved to the server, and does not 1320 yet have its eventual true <b>id</b>, but already needs to be visible in the UI. 1321 </p> 1322 1323 <p id="Model-attributes"> 1324 <b class="header">attributes</b><code>model.attributes</code> 1325 <br /> 1326 The <b>attributes</b> property is the internal hash containing the model's 1327 state — usually (but not necessarily) a form of the JSON object 1328 representing the model data on the server. It's often a straightforward 1329 serialization of a row from the database, but it could also be client-side 1330 computed state. 1331 </p> 1332 1333 <p> 1334 Please use <a href="#Model-set">set</a> to update the <b>attributes</b> 1335 instead of modifying them directly. If you'd like to retrieve and munge a 1336 copy of the model's attributes, use <tt>_.clone(model.attributes)</tt> 1337 instead. 1338 </p> 1339 1340 <p class="warning"> 1341 Due to the fact that <a href="#Events">Events</a> accepts space separated 1342 lists of events, attribute names should not include spaces. 1343 </p> 1344 1345 <p id="Model-changed"> 1346 <b class="header">changed</b><code>model.changed</code> 1347 <br /> 1348 The <b>changed</b> property is the internal hash containing all the attributes 1349 that have changed since its last <a href="#Model-set">set</a>. 1350 Please do not update <b>changed</b> directly since its state is internally maintained 1351 by <a href="#Model-set">set</a>. A copy of <b>changed</b> can be acquired from 1352 <a href="#Model-changedAttributes">changedAttributes</a>. 1353 </p> 1354 1355 <p id="Model-defaults"> 1356 <b class="header">defaults</b><code>model.defaults or model.defaults()</code> 1357 <br /> 1358 The <b>defaults</b> hash (or function) can be used to specify the default 1359 attributes for your model. When creating an instance of the model, 1360 any unspecified attributes will be set to their default value. 1361 </p> 1362 1363<pre class="runnable"> 1364var Meal = Backbone.Model.extend({ 1365 defaults: { 1366 "appetizer": "caesar salad", 1367 "entree": "ravioli", 1368 "dessert": "cheesecake" 1369 } 1370}); 1371 1372alert("Dessert will be " + (new Meal).get('dessert')); 1373</pre> 1374 1375 <p class="warning"> 1376 Remember that in JavaScript, objects are passed by reference, so if you 1377 include an object as a default value, it will be shared among all instances. 1378 Instead, define <b>defaults</b> as a function. 1379 </p> 1380 1381 <p id="Model-toJSON"> 1382 <b class="header">toJSON</b><code>model.toJSON([options])</code> 1383 <br /> 1384 Return a shallow copy of the model's <a href="#Model-attributes">attributes</a> 1385 for JSON stringification. This can be used for persistence, 1386 serialization, or for augmentation before being sent to the server. The 1387 name of this method is a bit confusing, as it doesn't actually return a 1388 JSON string — but I'm afraid that it's the way that the 1389 <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior">JavaScript API for <b>JSON.stringify</b></a> 1390 works. 1391 </p> 1392 1393<pre class="runnable"> 1394var artist = new Backbone.Model({ 1395 firstName: "Wassily", 1396 lastName: "Kandinsky" 1397}); 1398 1399artist.set({birthday: "December 16, 1866"}); 1400 1401alert(JSON.stringify(artist)); 1402</pre> 1403 1404 <p id="Model-sync"> 1405 <b class="header">sync</b><code>model.sync(method, model, [options])</code> 1406 <br /> 1407 Uses <a href="#Sync">Backbone.sync</a> to persist the state of a model to 1408 the server. Can be overridden for custom behavior. 1409 </p> 1410 1411 <p id="Model-fetch"> 1412 <b class="header">fetch</b><code>model.fetch([options])</code> 1413 <br /> 1414 Merges the model's state with attributes fetched from the server by 1415 delegating to <a href="#Sync">Backbone.sync</a>. Returns a 1416 <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a>. 1417 Useful if the model has never 1418 been populated with data, or if you'd like to ensure that you have the 1419 latest server state. Triggers a <tt>"change"</tt> event if the 1420 server's state differs from the current attributes. <tt>fetch</tt> accepts 1421 <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which 1422 are both passed <tt>(model, response, options)</tt> as arguments. 1423 </p> 1424 1425<pre> 1426// Poll every 10 seconds to keep the channel model up-to-date. 1427setInterval(function() { 1428 channel.fetch(); 1429}, 10000); 1430</pre> 1431 1432 <p id="Model-save"> 1433 <b class="header">save</b><code>model.save([attributes], [options])</code> 1434 <br /> 1435 Save a model to your database (or alternative persistence layer), 1436 by delegating to <a href="#Sync">Backbone.sync</a>. Returns a 1437 <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a> if 1438 validation is successful and <tt>false</tt> otherwise. The <b>attributes</b> 1439 hash (as in <a href="#Model-set">set</a>) should contain the attributes 1440 you'd like to change — keys that aren't mentioned won't be altered — but, 1441 a <i>complete representation</i> of the resource will be sent to the server. 1442 As with <tt>set</tt>, you may pass individual keys and values instead of a hash. 1443 If the model has a <a href="#Model-validate">validate</a> 1444 method, and validation fails, the model will not be saved. If the model 1445 <a href="#Model-isNew">isNew</a>, the save will be a <tt>"create"</tt> 1446 (HTTP <tt>POST</tt>), if the model already 1447 exists on the server, the save will be an <tt>"update"</tt> (HTTP <tt>PUT</tt>). 1448 </p> 1449 1450 <p> 1451 If instead, you'd only like the <i>changed</i> attributes to be sent to the 1452 server, call <tt>model.save(attrs, {patch: true})</tt>. You'll get an HTTP 1453 <tt>PATCH</tt> request to the server with just the passed-in attributes. 1454 </p> 1455 1456 <p> 1457 Calling <tt>save</tt> with new attributes will cause a <tt>"change"</tt> 1458 event immediately, a <tt>"request"</tt> event as the Ajax request begins to 1459 go to the server, and a <tt>"sync"</tt> event after the server has acknowledged 1460 the successful change. Pass <tt>{wait: true}</tt> if you'd like to wait 1461 for the server before setting the new attributes on the model. 1462 </p> 1463 1464 <p> 1465 In the following example, notice how our overridden version 1466 of <tt>Backbone.sync</tt> receives a <tt>"create"</tt> request 1467 the first time the model is saved and an <tt>"update"</tt> 1468 request the second time. 1469 </p> 1470 1471<pre class="runnable"> 1472Backbone.sync = function(method, model) { 1473 alert(method + ": " + JSON.stringify(model)); 1474 model.set('id', 1); 1475}; 1476 1477var book = new Backbone.Model({ 1478 title: "The Rough Riders", 1479 author: "Theodore Roosevelt" 1480}); 1481 1482book.save(); 1483 1484book.save({author: "Teddy"}); 1485</pre> 1486 1487 <p> 1488 <b>save</b> accepts <tt>success</tt> and <tt>error</tt> callbacks in the 1489 options hash, which will be passed the arguments <tt>(model, response, options)</tt>. 1490 If a server-side validation fails, return a non-<tt>200</tt> 1491 HTTP response code, along with an error response in text or JSON. 1492 </p> 1493 1494<pre> 1495book.save("author", "F.D.R.", {error: function(){ ... }}); 1496</pre> 1497 1498 <p id="Model-destroy"> 1499 <b class="header">destroy</b><code>model.destroy([options])</code> 1500 <br /> 1501 Destroys the model on the server by delegating an HTTP <tt>DELETE</tt> 1502 request to <a href="#Sync">Backbone.sync</a>. Returns a 1503 <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a> object, or 1504 <tt>false</tt> if the model <a href="#Model-isNew">isNew</a>. Accepts 1505 <tt>success</tt> and <tt>error</tt> callbacks in the options hash, which 1506 will be passed <tt>(model, response, options)</tt>. 1507 Triggers a <tt>"destroy"</tt> event on the model, which will bubble up 1508 through any collections that contain it, a <tt>"request"</tt> event as it 1509 begins the Ajax request to the server, and a <tt>"sync"</tt> event, after 1510 the server has successfully acknowledged the model's deletion. Pass 1511 <tt>{wait: true}</tt> if you'd like to wait for the server to respond 1512 before removing the model from the collection. 1513 </p> 1514 1515<pre> 1516book.destroy({success: function(model, response) { 1517 ... 1518}}); 1519</pre> 1520 1521 <p id="Model-Underscore-Methods"> 1522 <b class="header">Underscore Methods (9)</b> 1523 <br /> 1524 Backbone proxies to <b>Underscore.js</b> to provide 9 object functions 1525 on <b>Backbone.Model</b>. They aren't all documented here, but 1526 you can take a look at the Underscore documentation for the full details… 1527 </p> 1528 1529 <ul class="small"> 1530 <li><a href="http://underscorejs.org/#keys">keys</a></li> 1531 <li><a href="http://underscorejs.org/#values">values</a></li> 1532 <li><a href="http://underscorejs.org/#pairs">pairs</a></li> 1533 <li><a href="http://underscorejs.org/#invert">invert</a></li> 1534 <li><a href="http://underscorejs.org/#pick">pick</a></li> 1535 <li><a href="http://underscorejs.org/#omit">omit</a></li> 1536 <li><a href="http://underscorejs.org/#chain">chain</a></li> 1537 <li><a href="http://underscorejs.org/#isEmpty">isEmpty</a></li> 1538 </ul> 1539 1540<pre> 1541user.pick('first_name', 'last_name', 'email'); 1542 1543chapters.keys().join(', '); 1544</pre> 1545 1546 <p id="Model-validate"> 1547 <b class="header">validate</b><code>model.validate(attributes, options)</code> 1548 <br /> 1549 This method is left undefined and you're encouraged to override it with 1550 any custom validation logic you have that can be performed in JavaScript. 1551 If the attributes are valid, don't return anything from <b>validate</b>; 1552 if they are invalid return an error of your choosing. It can be as 1553 simple as a string error message to be displayed, or a complete error 1554 object that describes the error programmatically. 1555 </p> 1556 1557 <p> 1558 By default <tt>save</tt> checks <b>validate</b> before 1559 setting any attributes but you may also tell <tt>set</tt> to validate 1560 the new attributes by passing <tt>{validate: true}</tt> as an option. 1561 The <b>validate</b> method receives the model attributes as well as any 1562 options passed to <tt>set</tt> or <tt>save</tt>, if <b>validate</b> 1563 returns an error, <tt>save</tt> does not continue, the model attributes 1564 are not modified on the server, an <tt>"invalid"</tt> event is triggered, 1565 and the <tt>validationError</tt> property is set on the model with the 1566 value returned by this method. 1567 </p> 1568 1569<pre class="runnable"> 1570var Chapter = Backbone.Model.extend({ 1571 validate: function(attrs, options) { 1572 if (attrs.end < attrs.start) { 1573 return "can't end before it starts"; 1574 } 1575 } 1576}); 1577 1578var one = new Chapter({ 1579 title : "Chapter One: The Beginning" 1580}); 1581 1582one.on("invalid", function(model, error) { 1583 alert(model.get("title") + " " + error); 1584}); 1585 1586one.save({ 1587 start: 15, 1588 end: 10 1589}); 1590</pre> 1591 1592 <p> 1593 <tt>"invalid"</tt> events are useful for providing coarse-grained error 1594 messages at the model or collection level. 1595 </p> 1596 1597 <p id="Model-validationError"> 1598 <b class="header">validationError</b><code>model.validationError</code> 1599 <br /> 1600 The value returned by <a href="#Model-validate">validate</a> during the last failed validation. 1601 </p> 1602 1603 <p id="Model-isValid"> 1604 <b class="header">isValid</b><code>model.isValid(options)</code> 1605 <br /> 1606 Run <a href="#Model-validate">validate</a> to check the model state. 1607 </p> 1608 1609 <p> 1610 The <tt>validate</tt> method receives the model attributes as well as any 1611 options passed to <b>isValid</b>, if <tt>validate</tt> returns an error 1612 an <tt>"invalid"</tt> event is triggered, and the error is set on the 1613 model in the <tt>validationError</tt> property. 1614 </p> 1615 1616<pre class="runnable"> 1617var Chapter = Backbone.Model.extend({ 1618 validate: function(attrs, options) { 1619 if (attrs.end < attrs.start) { 1620 return "can't end before it starts"; 1621 } 1622 } 1623}); 1624 1625var one = new Chapter({ 1626 title : "Chapter One: The Beginning" 1627}); 1628 1629one.set({ 1630 start: 15, 1631 end: 10 1632}); 1633 1634if (!one.isValid()) { 1635 alert(one.get("title") + " " + one.validationError); 1636} 1637</pre> 1638 1639 <p id="Model-url"> 1640 <b class="header">url</b><code>model.url()</code> 1641 <br /> 1642 Returns the relative URL where the model's resource would be located on 1643 the server. If your models are located somewhere else, override this method 1644 with the correct logic. Generates URLs of the form: <tt>"[collection.url]/[id]"</tt> 1645 by default, but you may override by specifying an explicit <tt>urlRoot</tt> 1646 if the model's collection shouldn't be taken into account. 1647 </p> 1648 1649 <p> 1650 Delegates to <a href="#Collection-url">Collection#url</a> to generate the 1651 URL, so make sure that you have it defined, or a <a href="#Model-urlRoot">urlRoot</a> 1652 property, if all models of this class share a common root URL. 1653 A model with an id of <tt>101</tt>, stored in a 1654 <a href="#Collection">Backbone.Collection</a> with a <tt>url</tt> of <tt>"/documents/7/notes"</tt>, 1655 would have this URL: <tt>"/documents/7/notes/101"</tt> 1656 </p> 1657 1658 <p id="Model-urlRoot"> 1659 <b class="header">urlRoot</b><code>model.urlRoot or model.urlRoot()</code> 1660 <br /> 1661 Specify a <tt>urlRoot</tt> if you're using a model <i>outside</i> of a collection, 1662 to enable the default <a href="#Model-url">url</a> function to generate 1663 URLs based on the model id. <tt>"[urlRoot]/id"</tt><br /> 1664 Normally, you won't need to define this. 1665 Note that <tt>urlRoot</tt> may also be a function. 1666 </p> 1667 1668<pre class="runnable"> 1669var Book = Backbone.Model.extend({urlRoot : '/books'}); 1670 1671var solaris = new Book({id: "1083-lem-solaris"}); 1672 1673alert(solaris.url()); 1674</pre> 1675 1676 <p id="Model-parse"> 1677 <b class="header">parse</b><code>model.parse(response, options)</code> 1678 <br /> 1679 <b>parse</b> is called whenever a model's data is returned by the 1680 server, in <a href="#Model-fetch">fetch</a>, and <a href="#Model-save">save</a>. 1681 The function is passed the raw <tt>response</tt> object, and should return 1682 the attributes hash to be <a href="#Model-set">set</a> on the model. The 1683 default implementation is a no-op, simply passing through the JSON response. 1684 Override this if you need to work with a preexisting API, or better namespace 1685 your responses. 1686 </p> 1687 1688 <p> 1689 If you're working with a Rails backend that has a version prior to 3.1, 1690 you'll notice that its default <tt>to_json</tt> implementation includes 1691 a model's attributes under a namespace. To disable this behavior for 1692 seamless Backbone integration, set: 1693 </p> 1694 1695<pre> 1696ActiveRecord::Base.include_root_in_json = false 1697</pre> 1698 1699 <p id="Model-clone"> 1700 <b class="header">clone</b><code>model.clone()</code> 1701 <br /> 1702 Returns a new instance of the model with identical attributes. 1703 </p> 1704 1705 <p id="Model-isNew"> 1706 <b class="header">isNew</b><code>model.isNew()</code> 1707 <br /> 1708 Has this model been saved to the server yet? If the model does not yet have 1709 an <tt>id</tt>, it is considered to be new. 1710 </p> 1711 1712 <p id="Model-hasChanged"> 1713 <b class="header">hasChanged</b><code>model.hasChanged([attribute])</code> 1714 <br /> 1715 Has the model changed since its last <a href="#Model-set">set</a>? If an <b>attribute</b> 1716 is passed, returns <tt>true</tt> if that specific attribute has changed. 1717 </p> 1718 1719 <p class="warning"> 1720 Note that this method, and the following change-related ones, 1721 are only useful during the course of a <tt>"change"</tt> event. 1722 </p> 1723 1724<pre> 1725book.on("change", function() { 1726 if (book.hasChanged("title")) { 1727 ... 1728 } 1729}); 1730</pre> 1731 1732 <p id="Model-changedAttributes"> 1733 <b class="header">changedAttributes</b><code>model.changedAttributes([attributes])</code> 1734 <br /> 1735 Retrieve a hash of only the model's attributes that have changed since the last 1736 <a href="#Model-set">set</a>, or <tt>false</tt> if there are none. Optionally, an external 1737 <b>attributes</b> hash can be passed in, returning the attributes in that 1738 hash which differ from the model. This can be used to figure out which 1739 portions of a view should be updated, or what calls 1740 need to be made to sync the changes to the server. 1741 </p> 1742 1743 <p id="Model-previous"> 1744 <b class="header">previous</b><code>model.previous(attribute)</code> 1745 <br /> 1746 During a <tt>"change"</tt> event, this method can be used to get the 1747 previous value of a changed attribute. 1748 </p> 1749 1750<pre class="runnable"> 1751var bill = new Backbone.Model({ 1752 name: "Bill Smith" 1753}); 1754 1755bill.on("change:name", function(model, name) { 1756 alert("Changed name from " + bill.previous("name") + " to " + name); 1757}); 1758 1759bill.set({name : "Bill Jones"}); 1760</pre> 1761 1762 <p id="Model-previousAttributes"> 1763 <b class="header">previousAttributes</b><code>model.previousAttributes()</code> 1764 <br /> 1765 Return a copy of the model's previous attributes. Useful for getting a 1766 diff between versions of a model, or getting back to a valid state after 1767 an error occurs. 1768 </p> 1769 1770 <h2 id="Collection">Backbone.Collection</h2> 1771 1772 <p> 1773 Collections are ordered sets of models. You can bind <tt>"change"</tt> events 1774 to be notified when any model in the collection has been modified, 1775 listen for <tt>"add"</tt> and <tt>"remove"</tt> events, <tt>fetch</tt> 1776 the collection from the server, and use a full suite of 1777 <a href="#Collection-Underscore-Methods">Underscore.js methods</a>. 1778 </p> 1779 1780 <p> 1781 Any event that is triggered on a model in a collection will also be 1782 triggered on the collection directly, for convenience. 1783 This allows you to listen for changes to specific attributes in any 1784 model in a collection, for example: 1785 <tt>documents.on("change:selected", ...)</tt> 1786 </p> 1787 1788 <p id="Collection-extend"> 1789 <b class="header">extend</b><code>Backbone.Collection.extend(properties, [classProperties])</code> 1790 <br /> 1791 To create a <b>Collection</b> class of your own, extend <b>Backbone.Collection</b>, 1792 providing instance <b>properties</b>, as well as optional <b>classProperties</b> to be attached 1793 directly to the collection's constructor function. 1794 </p> 1795 1796 <p id="Collection-model"> 1797 <b class="header">model</b><code>collection.model([attrs], [options])</code> 1798 <br /> 1799 Override this property to specify the model class that the collection contains. 1800 If defined, you can pass raw attributes objects (and arrays) and options to 1801 <a href="#Collection-add">add</a>, <a href="#Collection-create">create</a>, 1802 and <a href="#Collection-reset">reset</a>, and the attributes will be 1803 converted into a model of the proper type using the provided options, if any. 1804 </p> 1805 1806<pre> 1807var Library = Backbone.Collection.extend({ 1808 model: Book 1809}); 1810</pre> 1811 1812 <p> 1813 A collection can also contain polymorphic models by overriding this property 1814 with a constructor that returns a model. 1815 </p> 1816 1817<pre> 1818var Library = Backbone.Collection.extend({ 1819 1820 model: function(attrs, options) { 1821 if (condition) { 1822 return new PublicDocument(attrs, options); 1823 } else { 1824 return new PrivateDocument(attrs, options); 1825 } 1826 } 1827 1828}); 1829</pre> 1830 1831 <p id="Collection-modelId"> 1832 <b class="header">modelId</b><code>collection.modelId(attrs)</code> 1833 <br /> 1834 Override this method to return the value the collection will use to 1835 identify a model given its attributes. Useful for combining models from 1836 multiple tables with different <a href="#Model-idAttribute"><tt>idAttribute</tt></a> 1837 values into a single collection. 1838 </p> 1839 1840 <p> 1841 By default returns the value of the attributes' 1842 <a href="#Model-idAttribute"><tt>idAttribute</tt></a> 1843 from the collection's model class or failing that, <tt>id</tt>. If 1844 your collection uses a <a href="#Collection-model">model factory</a> and 1845 those models have an <tt>idAttribute</tt> other than <tt>id</tt> you must 1846 override this method. 1847 </p> 1848 1849<pre class="runnable"> 1850var Library = Backbone.Collection.extend({ 1851 modelId: function(attrs) { 1852 return attrs.type + attrs.id; 1853 } 1854}); 1855 1856var library = new Library([ 1857 {type: 'dvd', id: 1}, 1858 {type: 'vhs', id: 1} 1859]); 1860 1861var dvdId = library.get('dvd1').id; 1862var vhsId = library.get('vhs1').id; 1863alert('dvd: ' + dvdId + ', vhs: ' + vhsId); 1864</pre> 1865 1866 <p id="Collection-preinitialize"> 1867 <b class="header">preinitialize</b><code>new Backbone.Collection([models], [options])</code> 1868 <br /> 1869 For use with collections as ES classes. If you define a <b>preinitialize</b> 1870 method, it will be invoked when the Collection is first created and before 1871 any instantiation logic is run for the Collection. 1872 </p> 1873 1874<pre> 1875class Library extends Backbone.Collection { 1876 preinitialize() { 1877 this.on("add", function() { 1878 console.log("Add model event got fired!"); 1879 }); 1880 } 1881} 1882</pre> 1883 1884 <p id="Collection-constructor"> 1885 <b class="header">constructor / initialize</b><code>new Backbone.Collection([models], [options])</code> 1886 <br /> 1887 When creating a Collection, you may choose to pass in the initial array 1888 of <b>models</b>. The collection's <a href="#Collection-comparator">comparator</a> 1889 may be included as an option. Passing <tt>false</tt> as the 1890 comparator option will prevent sorting. If you define an 1891 <b>initialize</b> function, it will be invoked when the collection is 1892 created. There are a couple of options that, if provided, are attached to 1893 the collection directly: <tt>model</tt> and <tt>comparator</tt>.<br /> 1894 Pass <tt>null</tt> for <tt>models</tt> to create an empty Collection with <tt>options</tt>. 1895 </p> 1896 1897<pre> 1898var tabs = new TabSet([tab1, tab2, tab3]); 1899var spaces = new Backbone.Collection(null, { 1900 model: Space 1901}); 1902</pre> 1903 1904 <p id="Collection-models"> 1905 <b class="header">models</b><code>collection.models</code> 1906 <br /> 1907 Raw access to the JavaScript array of models inside of the collection. Usually you'll 1908 want to use <tt>get</tt>, <tt>at</tt>, or the <b>Underscore methods</b> 1909 to access model objects, but occasionally a direct reference to the array 1910 is desired. 1911 </p> 1912 1913 <p id="Collection-toJSON"> 1914 <b class="header">toJSON</b><code>collection.toJSON([options])</code> 1915 <br /> 1916 Return an array containing the attributes hash of each model 1917 (via <a href="#Model-toJSON">toJSON</a>) in the 1918 collection. This can be used to serialize and persist the 1919 collection as a whole. The name of this method is a bit confusing, because 1920 it conforms to 1921 <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior">JavaScript's JSON API</a>. 1922 </p> 1923 1924<pre class="runnable"> 1925var collection = new Backbone.Collection([ 1926 {name: "Tim", age: 5}, 1927 {name: "Ida", age: 26}, 1928 {name: "Rob", age: 55} 1929]); 1930 1931alert(JSON.stringify(collection)); 1932</pre> 1933 1934 <p id="Collection-sync"> 1935 <b class="header">sync</b><code>collection.sync(method, collection, [options])</code> 1936 <br /> 1937 Uses <a href="#Sync">Backbone.sync</a> to persist the state of a 1938 collection to the server. Can be overridden for custom behavior. 1939 </p> 1940 1941 <p id="Collection-Underscore-Methods"> 1942 <b class="header">Underscore Methods (46)</b> 1943 <br /> 1944 Backbone proxies to <b>Underscore.js</b> to provide 46 iteration functions 1945 on <b>Backbone.Collection</b>. They aren't all documented here, but 1946 you can take a look at the Underscore documentation for the full details… 1947 </p> 1948 1949 <p> 1950 Most methods can take an object or string to support model-attribute-style 1951 predicates or a function that receives the model instance as an argument. 1952 </p> 1953 1954 <ul class="small"> 1955 <li><a href="http://underscorejs.org/#each">forEach (each)</a></li> 1956 <li><a href="http://underscorejs.org/#map">map (collect)</a></li> 1957 <li><a href="http://underscorejs.org/#reduce">reduce (foldl, inject)</a></li> 1958 <li><a href="http://underscorejs.org/#reduceRight">reduceRight (foldr)</a></li> 1959 <li><a href="http://underscorejs.org/#find">find (detect)</a></li> 1960 <li><a href="http://underscorejs.org/#findIndex">findIndex</a></li> 1961 <li><a href="http://underscorejs.org/#findLastIndex">findLastIndex</a></li> 1962 <li><a href="http://underscorejs.org/#filter">filter (select)</a></li> 1963 <li><a href="http://underscorejs.org/#reject">reject</a></li> 1964 <li><a href="http://underscorejs.org/#every">every (all)</a></li> 1965 <li><a href="http://underscorejs.org/#some">some (any)</a></li> 1966 <li><a href="http://underscorejs.org/#contains">contains (includes)</a></li> 1967 <li><a href="http://underscorejs.org/#invoke">invoke</a></li> 1968 <li><a href="http://underscorejs.org/#max">max</a></li> 1969 <li><a href="http://underscorejs.org/#min">min</a></li> 1970 <li><a href="http://underscorejs.org/#sortBy">sortBy</a></li> 1971 <li><a href="http://underscorejs.org/#groupBy">groupBy</a></li> 1972 <li><a href="http://underscorejs.org/#shuffle">shuffle</a></li> 1973 <li><a href="http://underscorejs.org/#toArray">toArray</a></li> 1974 <li><a href="http://underscorejs.org/#size">size</a></li> 1975 <li><a href="http://underscorejs.org/#first">first (head, take)</a></li> 1976 <li><a href="http://underscorejs.org/#initial">initial</a></li> 1977 <li><a href="http://underscorejs.org/#rest">rest (tail, drop)</a></li> 1978 <li><a href="http://underscorejs.org/#last">last</a></li> 1979 <li><a href="http://underscorejs.org/#without">without</a></li> 1980 <li><a href="http://underscorejs.org/#indexOf">indexOf</a></li> 1981 <li><a href="http://underscorejs.org/#lastIndexOf">lastIndexOf</a></li> 1982 <li><a href="http://underscorejs.org/#isEmpty">isEmpty</a></li> 1983 <li><a href="http://underscorejs.org/#chain">chain</a></li> 1984 <li><a href="http://underscorejs.org/#difference">difference</a></li> 1985 <li><a href="http://underscorejs.org/#sample">sample</a></li> 1986 <li><a href="http://underscorejs.org/#partition">partition</a></li> 1987 <li><a href="http://underscorejs.org/#countBy">countBy</a></li> 1988 <li><a href="http://underscorejs.org/#indexBy">indexBy</a></li> 1989 </ul> 1990 1991<pre> 1992books.each(function(book) { 1993 book.publish(); 1994}); 1995 1996var titles = books.map("title"); 1997 1998var publishedBooks = books.filter({published: true}); 1999 2000var alphabetical = books.sortBy(function(book) { 2001 return book.author.get("name").toLowerCase(); 2002}); 2003 2004var randomThree = books.sample(3); 2005</pre> 2006 2007 <p id="Collection-add"> 2008 <b class="header">add</b><code>collection.add(models, [options])</code> 2009 <br /> 2010 Add a model (or an array of models) to the collection, firing an <tt>"add"</tt> 2011 event for each model, and an <tt>"update"</tt> event afterwards. If a <a href="#Collection-model">model</a> property is defined, you may also pass 2012 raw attributes objects and options, and have them be vivified as instances of the model using 2013 the provided options. 2014 Returns the added (or preexisting, if duplicate) models. 2015 Pass <tt>{at: index}</tt> to splice the model into the collection at the 2016 specified <tt>index</tt>. If you're adding models to the collection that are 2017 <i>already</i> in the collection, they'll be ignored, unless you pass 2018 <tt>{merge: true}</tt>, in which case their attributes will be merged 2019 into the corresponding models, firing any appropriate <tt>"change"</tt> events. 2020 </p> 2021 2022<pre class="runnable"> 2023var ships = new Backbone.Collection; 2024 2025ships.on("add", function(ship) { 2026 alert("Ahoy " + ship.get("name") + "!"); 2027}); 2028 2029ships.add([ 2030 {name: "Flying Dutchman"}, 2031 {name: "Black Pearl"} 2032]); 2033</pre> 2034 2035 <p class="warning"> 2036 Note that adding the same model (a model with the same <tt>id</tt>) to 2037 a collection more than once <br /> is a no-op. 2038 </p> 2039 2040 <p id="Collection-remove"> 2041 <b class="header">remove</b><code>collection.remove(models, [options])</code> 2042 <br /> 2043 Remove a model (or an array of models) from the collection, and return 2044 them. Each model can be a Model instance, an <tt>id</tt> string or a JS 2045 object, any value acceptable as the <tt>id</tt> argument of 2046 <a href="#Collection-get"><tt>collection.get</tt></a>. 2047 Fires a <tt>"remove"</tt> event for each model, and a single 2048 <tt>"update"</tt> event afterwards, unless <tt>{silent: true}</tt> is passed. 2049 The model's index before removal is available to listeners as 2050 <tt>options.index</tt>. 2051 </p> 2052 2053 <p id="Collection-reset"> 2054 <b class="header">reset</b><code>collection.reset([models], [options])</code> 2055 <br /> 2056 Adding and removing models one at a time is all well and good, but sometimes 2057 you have so many models to change that you'd rather just update the collection 2058 in bulk. Use <b>reset</b> to replace a collection with a new list 2059 of models (or attribute hashes), triggering a single <tt>"reset"</tt> event 2060 on completion, and <i>without</i> triggering any add or remove events on any models. 2061 Returns the newly-set models. 2062 For convenience, within a <tt>"reset"</tt> event, the list of any 2063 previous models is available as <tt>options.previousModels</tt>.<br /> 2064 Pass <tt>null</tt> for <tt>models</tt> to empty your Collection with <tt>options</tt>. 2065 </p> 2066 2067 <p> 2068 Here's an example using <b>reset</b> to bootstrap a collection during initial page load, 2069 in a Rails application: 2070 </p> 2071 2072<pre> 2073<script> 2074 var accounts = new Backbone.Collection; 2075 accounts.reset(<%= @accounts.to_json %>); 2076</script> 2077</pre> 2078 2079 <p> 2080 Calling <tt>collection.reset()</tt> without passing any models as arguments 2081 will empty the entire collection. 2082 </p> 2083 2084 <p id="Collection-set"> 2085 <b class="header">set</b><code>collection.set(models, [options])</code> 2086 <br /> 2087 The <b>set</b> method performs a "smart" update of the collection 2088 with the passed list of models. If a model in the list isn't yet in the 2089 collection it will be added; if the model is already in the collection 2090 its attributes will be merged; and if the collection contains any models that 2091 <i>aren't</i> present in the list, they'll be removed. All of the appropriate 2092 <tt>"add"</tt>, <tt>"remove"</tt>, and <tt>"change"</tt> events are fired 2093 as this happens. Returns the touched models in the collection. 2094 If you'd like to customize the behavior, you can disable 2095 it with options: <tt>{add: false}</tt>, <tt>{remove: false}</tt>, or <tt>{merge: false}</tt>. 2096 </p> 2097 2098<pre> 2099var vanHalen = new Backbone.Collection([eddie, alex, stone, roth]); 2100 2101vanHalen.set([eddie, alex, stone, hagar]); 2102 2103// Fires a "remove" event for roth, and an "add" event for "hagar". 2104// Updates any of stone, alex, and eddie's attributes that may have 2105// changed over the years. 2106</pre> 2107 2108 <p id="Collection-get"> 2109 <b class="header">get</b><code>collection.get(id)</code> 2110 <br /> 2111 Get a model from a collection, specified by an <a href="#Model-id">id</a>, 2112 a <a href="#Model-cid">cid</a>, or by passing in a <b>model</b>. 2113 </p> 2114 2115<pre> 2116var book = library.get(110); 2117</pre> 2118 2119 <p id="Collection-at"> 2120 <b class="header">at</b><code>collection.at(index)</code> 2121 <br /> 2122 Get a model from a collection, specified by index. Useful if your collection 2123 is sorted, and if your collection isn't sorted, <b>at</b> will still 2124 retrieve models in insertion order. When passed a negative index, it 2125 will retrieve the model from the back of the collection. 2126 </p> 2127 2128 <p id="Collection-push"> 2129 <b class="header">push</b><code>collection.push(model, [options])</code> 2130 <br /> 2131 Add a model at the end of a collection. Takes the same options as 2132 <a href="#Collection-add">add</a>. 2133 </p> 2134 2135 <p id="Collection-pop"> 2136 <b class="header">pop</b><code>collection.pop([options])</code> 2137 <br /> 2138 Remove and return the last model from a collection. Takes the same options as 2139 <a href="#Collection-remove">remove</a>. 2140 </p> 2141 2142 <p id="Collection-unshift"> 2143 <b class="header">unshift</b><code>collection.unshift(model, [options])</code> 2144 <br /> 2145 Add a model at the beginning of a collection. Takes the same options as 2146 <a href="#Collection-add">add</a>. 2147 </p> 2148 2149 <p id="Collection-shift"> 2150 <b class="header">shift</b><code>collection.shift([options])</code> 2151 <br /> 2152 Remove and return the first model from a collection. Takes the same options as 2153 <a href="#Collection-remove">remove</a>. 2154 </p> 2155 2156 <p id="Collection-slice"> 2157 <b class="header">slice</b><code>collection.slice(begin, end)</code> 2158 <br /> 2159 Return a shallow copy of this collection's models, using the same options as 2160 native 2161 <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">Array#slice</a>. 2162 </p> 2163 2164 <p id="Collection-length"> 2165 <b class="header">length</b><code>collection.length</code> 2166 <br /> 2167 Like an array, a Collection maintains a <tt>length</tt> property, counting 2168 the number of models it contains. 2169 </p> 2170 2171 <p id="Collection-comparator"> 2172 <b class="header">comparator</b><code>collection.comparator</code> 2173 <br /> 2174 By default there is no <b>comparator</b> for a collection. 2175 If you define a comparator, it will be used to sort the collection any 2176 time a model is added. 2177 A comparator can be defined as a 2178 <a href="http://underscorejs.org/#sortBy">sortBy</a> 2179 (pass a function that takes a single argument), 2180 as a 2181 <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">sort</a> 2182 (pass a comparator function that expects two arguments), 2183 or as a string indicating the attribute to sort by. 2184 </p> 2185 2186 <p> 2187 "sortBy" comparator functions take a model and return a numeric or string 2188 value by which the model should be ordered relative to others. 2189 "sort" comparator functions take two models, and return <tt>-1</tt> if 2190 the first model should come before the second, <tt>0</tt> if they are of 2191 the same rank and <tt>1</tt> if the first model should come after. 2192 <i>Note that Backbone depends on the arity of your comparator function to 2193 determine between the two styles, so be careful if your comparator function 2194 is bound.</i> 2195 </p> 2196 2197 <p> 2198 Note how even though all of the chapters in this example are added backwards, 2199 they come out in the proper order: 2200 </p> 2201 2202<pre class="runnable"> 2203var Chapter = Backbone.Model; 2204var chapters = new Backbone.Collection; 2205 2206chapters.comparator = 'page'; 2207 2208chapters.add(new Chapter({page: 9, title: "The End"})); 2209chapters.add(new Chapter({page: 5, title: "The Middle"})); 2210chapters.add(new Chapter({page: 1, title: "The Beginning"})); 2211 2212alert(chapters.pluck('title')); 2213</pre> 2214 2215 <p class="warning"> 2216 Collections with a comparator will not automatically re-sort if you 2217 later change model attributes, so you may wish to call 2218 <tt>sort</tt> after changing model attributes that would affect the order. 2219 </p> 2220 2221 <p id="Collection-sort"> 2222 <b class="header">sort</b><code>collection.sort([options])</code> 2223 <br /> 2224 Force a collection to re-sort itself. Note that a collection with a 2225 <a href="#Collection-comparator">comparator</a> will sort itself 2226 automatically whenever a model is added. To disable sorting when adding 2227 a model, pass <tt>{sort: false}</tt> to <tt>add</tt>. Calling <b>sort</b> 2228 triggers a <tt>"sort"</tt> event on the collection. 2229 </p> 2230 2231 <p id="Collection-pluck"> 2232 <b class="header">pluck</b><code>collection.pluck(attribute)</code> 2233 <br /> 2234 Pluck an attribute from each model in the collection. Equivalent to calling 2235 <tt>map</tt> and returning a single attribute from the iterator. 2236 </p> 2237 2238<pre class="runnable"> 2239var stooges = new Backbone.Collection([ 2240 {name: "Curly"}, 2241 {name: "Larry"}, 2242 {name: "Moe"} 2243]); 2244 2245var names = stooges.pluck("name"); 2246 2247alert(JSON.stringify(names)); 2248</pre> 2249 2250 <p id="Collection-where"> 2251 <b class="header">where</b><code>collection.where(attributes)</code> 2252 <br /> 2253 Return an array of all the models in a collection that match the 2254 passed <b>attributes</b>. Useful for simple cases of <tt>filter</tt>. 2255 </p> 2256 2257<pre class="runnable"> 2258var friends = new Backbone.Collection([ 2259 {name: "Athos", job: "Musketeer"}, 2260 {name: "Porthos", job: "Musketeer"}, 2261 {name: "Aramis", job: "Musketeer"}, 2262 {name: "d'Artagnan", job: "Guard"}, 2263]); 2264 2265var musketeers = friends.where({job: "Musketeer"}); 2266 2267alert(musketeers.length); 2268</pre> 2269 2270 <p id="Collection-findWhere"> 2271 <b class="header">findWhere</b><code>collection.findWhere(attributes)</code> 2272 <br /> 2273 Just like <a href="#Collection-where">where</a>, but directly returns only 2274 the first model in the collection that matches the passed <b>attributes</b>. 2275 If no model matches returns <tt>undefined</tt>. 2276 </p> 2277 2278 <p id="Collection-url"> 2279 <b class="header">url</b><code>collection.url or collection.url()</code> 2280 <br /> 2281 Set the <b>url</b> property (or function) on a collection to reference 2282 its location on the server. Models within the collection will use <b>url</b> 2283 to construct URLs of their own. 2284 </p> 2285 2286<pre> 2287var Notes = Backbone.Collection.extend({ 2288 url: '/notes' 2289}); 2290 2291// Or, something more sophisticated: 2292 2293var Notes = Backbone.Collection.extend({ 2294 url: function() { 2295 return this.document.url() + '/notes'; 2296 } 2297}); 2298</pre> 2299 2300 <p id="Collection-parse"> 2301 <b class="header">parse</b><code>collection.parse(response, options)</code> 2302 <br /> 2303 <b>parse</b> is called by Backbone whenever a collection's models are 2304 returned by the server, in <a href="#Collection-fetch">fetch</a>. 2305 The function is passed the raw <tt>response</tt> object, and should return 2306 the array of model attributes to be <a href="#Collection-add">added</a> 2307 to the collection. The default implementation is a no-op, simply passing 2308 through the JSON response. Override this if you need to work with a 2309 preexisting API, or better namespace your responses. 2310 </p> 2311 2312<pre> 2313var Tweets = Backbone.Collection.extend({ 2314 // The Twitter Search API returns tweets under "results". 2315 parse: function(response) { 2316 return response.results; 2317 } 2318}); 2319</pre> 2320 2321 <p id="Collection-clone"> 2322 <b class="header">clone</b><code>collection.clone()</code> 2323 <br /> 2324 Returns a new instance of the collection with an identical list of models. 2325 </p> 2326 2327 <p id="Collection-fetch"> 2328 <b class="header">fetch</b><code>collection.fetch([options])</code> 2329 <br /> 2330 Fetch the default set of models for this collection from the server, 2331 <a href="#Collection-set">setting</a> them on the collection when they arrive. 2332 The <b>options</b> hash takes <tt>success</tt> and <tt>error</tt> callbacks 2333 which will both be passed <tt>(collection, response, options)</tt> as arguments. 2334 When the model data returns from the server, it uses <a href="#Collection-set">set</a> 2335 to (intelligently) merge the fetched models, unless you pass <tt>{reset: true}</tt>, 2336 in which case the collection will be (efficiently) <a href="#Collection-reset">reset</a>. 2337 Delegates to <a href="#Sync">Backbone.sync</a> 2338 under the covers for custom persistence strategies and returns a 2339 <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a>. 2340 The server handler for <b>fetch</b> requests should return a JSON array of 2341 models. 2342 </p> 2343 2344<pre class="runnable"> 2345Backbone.sync = function(method, model) { 2346 alert(method + ": " + model.url); 2347}; 2348 2349var accounts = new Backbone.Collection; 2350accounts.url = '/accounts'; 2351 2352accounts.fetch(); 2353</pre> 2354 2355 <p> 2356 The behavior of <b>fetch</b> can be customized by using the available 2357 <a href="#Collection-set">set</a> options. For example, to fetch a 2358 collection, getting an <tt>"add"</tt> event for every new model, and 2359 a <tt>"change"</tt> event for every changed existing model, without 2360 removing anything: <tt>collection.fetch({remove: false})</tt> 2361 </p> 2362 2363 <p> 2364 <b>jQuery.ajax</b> options can also be passed directly as <b>fetch</b> options, 2365 so to fetch a specific page of a paginated collection: 2366 <tt>Documents.fetch({data: {page: 3}})</tt> 2367 </p> 2368 2369 <p> 2370 Note that <b>fetch</b> should not be used to populate collections on 2371 page load — all models needed at load time should already be 2372 <a href="#FAQ-bootstrap">bootstrapped</a> in to place. <b>fetch</b> is 2373 intended for lazily-loading models for interfaces that are not needed 2374 immediately: for example, documents with collections of notes that may be 2375 toggled open and closed. 2376 </p> 2377 2378 <p id="Collection-create"> 2379 <b class="header">create</b><code>collection.create(attributes, [options])</code> 2380 <br /> 2381 Convenience to create a new instance of a model within a collection. 2382 Equivalent to instantiating a model with a hash of attributes, 2383 saving the model to the server, and adding the model to the set after being 2384 successfully created. Returns the new model. If client-side validation 2385 failed, the model will be unsaved, with validation errors. 2386 In order for this to work, you should set the 2387 <a href="#Collection-model">model</a> property of the collection. 2388 The <b>create</b> method can accept either an attributes hash and options to be 2389 passed down during model instantiation or an existing, unsaved model object. 2390 </p> 2391 2392 <p> 2393 Creating a model will cause an immediate <tt>"add"</tt> event to be 2394 triggered on the collection, a <tt>"request"</tt> event as the new model is 2395 sent to the server, as well as a <tt>"sync"</tt> event, once the 2396 server has responded with the successful creation of the model. Pass <tt>{wait: true}</tt> 2397 if you'd like to wait for the server before adding the new model to the collection. 2398 </p> 2399 2400<pre> 2401var Library = Backbone.Collection.extend({ 2402 model: Book 2403}); 2404 2405var nypl = new Library; 2406 2407var othello = nypl.create({ 2408 title: "Othello", 2409 author: "William Shakespeare" 2410}); 2411</pre> 2412 2413 <p id="Collection-mixin"> 2414 <b class="header">mixin</b><code>Backbone.Collection.mixin(properties)</code> 2415 <br /> 2416 <code>mixin</code> provides a way to enhance the base <b>Backbone.Collection</b> 2417 and any collections which extend it. This can be used to add generic methods 2418 (e.g. additional <a href="#Collection-Underscore-Methods"><b>Underscore Methods</b></a>). 2419 </p> 2420 2421<pre> 2422Backbone.Collection.mixin({ 2423 sum: function(models, iteratee) { 2424 return _.reduce(models, function(s, m) { 2425 return s + iteratee(m); 2426 }, 0); 2427 } 2428}); 2429 2430var cart = new Backbone.Collection([ 2431 {price: 16, name: 'monopoly'}, 2432 {price: 5, name: 'deck of cards'}, 2433 {price: 20, name: 'chess'} 2434]); 2435 2436var cost = cart.sum('price'); 2437</pre> 2438 2439 <h2 id="Router">Backbone.Router</h2> 2440 2441 <p> 2442 Web applications often provide linkable, bookmarkable, shareable URLs for 2443 important locations in the app. Until recently, hash fragments 2444 (<tt>#page</tt>) were used to provide these permalinks, but with the 2445 arrival of the History API, it's now possible to use standard URLs (<tt>/page</tt>). 2446 <b>Backbone.Router</b> provides methods for routing client-side pages, and 2447 connecting them to actions and events. For browsers which don't yet support 2448 the History API, the Router handles graceful fallback and transparent 2449 translation to the fragment version of the URL. 2450 </p> 2451 2452 <p> 2453 During page load, after your application has finished creating all of its routers, 2454 be sure to call <tt>Backbone.history.start()</tt> or 2455 <tt>Backbone.history.start({pushState: true})</tt> to route the initial URL. 2456 </p> 2457 2458 <p id="Router-extend"> 2459 <b class="header">extend</b><code>Backbone.Router.extend(properties, [classProperties])</code> 2460 <br /> 2461 Get started by creating a custom router class. Define action functions that are 2462 triggered when certain URL fragments are 2463 matched, and provide a <a href="#Router-routes">routes</a> hash 2464 that pairs routes to actions. Note that you'll want to avoid using a 2465 leading slash in your route definitions: 2466 </p> 2467 2468<pre> 2469var Workspace = Backbone.Router.extend({ 2470 2471 routes: { 2472 "help": "help", // #help 2473 "search/:query": "search", // #search/kiwis 2474 "search/:query/p:page": "search" // #search/kiwis/p7 2475 }, 2476 2477 help: function() { 2478 ... 2479 }, 2480 2481 search: function(query, page) { 2482 ... 2483 } 2484 2485}); 2486</pre> 2487 2488 <p id="Router-routes"> 2489 <b class="header">routes</b><code>router.routes</code> 2490 <br /> 2491 The routes hash maps URLs with parameters to functions on your router 2492 (or just direct function definitions, if you prefer), 2493 similar to the <a href="#View">View</a>'s <a href="#View-delegateEvents">events hash</a>. 2494 Routes can contain parameter parts, <tt>:param</tt>, which match a single URL 2495 component between slashes; and splat parts <tt>*splat</tt>, which can match 2496 any number of URL components. Part of a route can be made optional by 2497 surrounding it in parentheses <tt>(/:optional)</tt>. 2498 </p> 2499 2500 <p> 2501 For example, a route of <tt>"search/:query/p:page"</tt> will match 2502 a fragment of <tt>#search/obama/p2</tt>, passing <tt>"obama"</tt> 2503 and <tt>"2"</tt> to the action as positional arguments. 2504 </p> 2505 2506 <p> 2507 A route of <tt>"file/*path"</tt> will match 2508 <tt>#file/folder/file.txt</tt>, passing 2509 <tt>"folder/file.txt"</tt> to the action. 2510 </p> 2511 2512 <p> 2513 A route of <tt>"docs/:section(/:subsection)"</tt> will match 2514 <tt>#docs/faq</tt> and <tt>#docs/faq/installing</tt>, passing 2515 <tt>"faq"</tt> to the action in the first case, and passing <tt>"faq"</tt> 2516 and <tt>"installing"</tt> to the action in the second. 2517 </p> 2518 2519 <p> 2520 A nested optional route of <tt>"docs(/:section)(/:subsection)"</tt> will match 2521 <tt>#docs</tt>, <tt>#docs/faq</tt>, and <tt>#docs/faq/installing</tt>, 2522 passing <tt>"faq"</tt> to the action in the second case, and passing <tt>"faq"</tt> 2523 and <tt>"installing"</tt> to the action in the third. 2524 </p> 2525 2526 <p> 2527 Trailing slashes are treated as part of the URL, and (correctly) treated 2528 as a unique route when accessed. <tt>docs</tt> and <tt>docs/</tt> will fire 2529 different callbacks. If you can't avoid generating both types of URLs, you 2530 can define a <tt>"docs(/)"</tt> matcher to capture both cases. 2531 </p> 2532 2533 <p> 2534 When the visitor presses the back button, or enters a URL, and a particular 2535 route is matched, the name of the action will be fired as an 2536 <a href="#Events">event</a>, so that other objects can listen to the router, 2537 and be notified. In the following example, visiting <tt>#help/uploading</tt> 2538 will fire a <tt>route:help</tt> event from the router. 2539 </p> 2540 2541<pre> 2542routes: { 2543 "help/:page": "help", 2544 "download/*path": "download", 2545 "folder/:name": "openFolder", 2546 "folder/:name-:mode": "openFolder" 2547} 2548</pre> 2549 2550<pre> 2551router.on("route:help", function(page) { 2552 ... 2553}); 2554</pre> 2555 2556 <p id="Router-preinitialize"> 2557 <b class="header">preinitialize</b><code>new Backbone.Router([options])</code> 2558 <br /> 2559 For use with routers as ES classes. If you define a <b>preinitialize</b> 2560 method, it will be invoked when the Router is first created and before 2561 any instantiation logic is run for the Router. 2562 </p> 2563 2564<pre> 2565class Router extends Backbone.Router { 2566 preinitialize() { 2567 // Override execute method 2568 this.execute = function(callback, args, name) { 2569 if (!loggedIn) { 2570 goToLogin(); 2571 return false; 2572 } 2573 args.push(parseQueryString(args.pop())); 2574 if (callback) callback.apply(this, args); 2575 } 2576 } 2577} 2578</pre> 2579 2580 <p id="Router-constructor"> 2581 <b class="header">constructor / initialize</b><code>new Router([options])</code> 2582 <br /> 2583 When creating a new router, you may pass its 2584 <a href="#Router-routes">routes</a> hash directly as an option, if you 2585 choose. All <tt>options</tt> will also be passed to your <tt>initialize</tt> 2586 function, if defined. 2587 </p> 2588 2589 <p id="Router-route"> 2590 <b class="header">route</b><code>router.route(route, name, [callback])</code> 2591 <br /> 2592 Manually create a route for the router, The <tt>route</tt> argument may 2593 be a <a href="#Router-routes">routing string</a> or regular expression. 2594 Each matching capture from the route or regular expression will be passed as 2595 an argument to the callback. The <tt>name</tt> argument will be triggered as 2596 a <tt>"route:name"</tt> event whenever the route is matched. If the 2597 <tt>callback</tt> argument is omitted <tt>router[name]</tt> will be used 2598 instead. Routes added later may override previously declared routes. 2599 </p> 2600 2601<pre> 2602initialize: function(options) { 2603 2604 // Matches #page/10, passing "10" 2605 this.route("page/:number", "page", function(number){ ... }); 2606 2607 // Matches /117-a/b/c/open, passing "117-a/b/c" to this.open 2608 this.route(/^(.*?)\/open$/, "open"); 2609 2610}, 2611 2612open: function(id) { ... } 2613</pre> 2614 2615 <p id="Router-navigate"> 2616 <b class="header">navigate</b><code>router.navigate(fragment, [options])</code> 2617 <br /> 2618 Whenever you reach a point in your application that you'd like to save 2619 as a URL, call <b>navigate</b> in order to update the URL. 2620 If you also wish to call the route function, set the <b>trigger</b> 2621 option to <tt>true</tt>. 2622 To update the URL without creating an entry in the browser's history, 2623 set the <b>replace</b> option to <tt>true</tt>. 2624 </p> 2625 2626<pre> 2627openPage: function(pageNumber) { 2628 this.document.pages.at(pageNumber).open(); 2629 this.navigate("page/" + pageNumber); 2630} 2631 2632# Or ... 2633 2634app.navigate("help/troubleshooting", {trigger: true}); 2635 2636# Or ... 2637 2638app.navigate("help/troubleshooting", {trigger: true, replace: true}); 2639</pre> 2640 2641 <p id="Router-execute"> 2642 <b class="header">execute</b><code>router.execute(callback, args, name)</code> 2643 <br /> 2644 This method is called internally within the router, whenever a route 2645 matches and its corresponding <b>callback</b> is about to be executed. 2646 Return <b>false</b> from execute to cancel the current transition. 2647 Override it to perform custom parsing or wrapping of your routes, for 2648 example, to parse query strings before handing them to your route 2649 callback, like so: 2650 </p> 2651 2652<pre> 2653var Router = Backbone.Router.extend({ 2654 execute: function(callback, args, name) { 2655 if (!loggedIn) { 2656 goToLogin(); 2657 return false; 2658 } 2659 args.push(parseQueryString(args.pop())); 2660 if (callback) callback.apply(this, args); 2661 } 2662}); 2663</pre> 2664 2665 <h2 id="History">Backbone.history</h2> 2666 2667 <p> 2668 <b>History</b> serves as a global router (per frame) to handle <tt>hashchange</tt> 2669 events or <tt>pushState</tt>, match the appropriate route, and trigger callbacks. 2670 You shouldn't ever have to create one of these yourself since <tt>Backbone.history</tt> 2671 already contains one. 2672 </p> 2673 2674 <p> 2675 <b>pushState</b> support exists on a purely opt-in basis in Backbone. 2676 Older browsers that don't support <tt>pushState</tt> will continue to use 2677 hash-based URL fragments, and if a hash URL is visited by a 2678 <tt>pushState</tt>-capable browser, it will be transparently upgraded to 2679 the true URL. Note that using real URLs requires your web server to be 2680 able to correctly render those pages, so back-end changes are required 2681 as well. For example, if you have a route of <tt>/documents/100</tt>, 2682 your web server must be able to serve that page, if the browser 2683 visits that URL directly. For full search-engine crawlability, it's best to 2684 have the server generate the complete HTML for the page ... but if it's a web 2685 application, just rendering the same content you would have for the root URL, 2686 and filling in the rest with Backbone Views and JavaScript works fine. 2687 </p> 2688 2689 <p id="History-start"> 2690 <b class="header">start</b><code>Backbone.history.start([options])</code> 2691 <br /> 2692 When all of your <a href="#Router">Routers</a> have been created, 2693 and all of the routes are set up properly, call <tt>Backbone.history.start()</tt> 2694 to begin monitoring <tt>hashchange</tt> events, and dispatching routes. 2695 Subsequent calls to <tt>Backbone.history.start()</tt> will throw an error, 2696 and <tt>Backbone.History.started</tt> is a boolean value indicating whether 2697 it has already been called. 2698 </p> 2699 2700 <p> 2701 To indicate that you'd like to use HTML5 <tt>pushState</tt> support in 2702 your application, use <tt>Backbone.history.start({pushState: true})</tt>. 2703 If you'd like to use <tt>pushState</tt>, but have browsers that don't support 2704 it natively use full page refreshes instead, you can add 2705 <tt>{hashChange: false}</tt> to the options. 2706 </p> 2707 2708 <p> 2709 If your application is not being served from the root url <tt>/</tt> of your 2710 domain, be sure to tell History where the root really is, as an option: 2711 <tt>Backbone.history.start({pushState: true, root: "/public/search/"})</tt> 2712 </p> 2713 2714 <p> 2715 When called, if a route succeeds with a match for the current URL, 2716 <tt>Backbone.history.start()</tt> returns <tt>true</tt>. If no defined 2717 route matches the current URL, it returns <tt>false</tt>. 2718 </p> 2719 2720 <p> 2721 If the server has already rendered the entire page, and you don't want the 2722 initial route to trigger when starting History, pass <tt>silent: true</tt>. 2723 </p> 2724 2725 <p> 2726 Because hash-based history in Internet Explorer relies on an 2727 <tt><iframe></tt>, be sure to call <tt>start()</tt> only after the DOM 2728 is ready. 2729 </p> 2730 2731<pre> 2732$(function(){ 2733 new WorkspaceRouter(); 2734 new HelpPaneRouter(); 2735 Backbone.history.start({pushState: true}); 2736}); 2737</pre> 2738 2739 <h2 id="Sync">Backbone.sync</h2> 2740 2741 <p> 2742 <b>Backbone.sync</b> is the function that Backbone calls every time it 2743 attempts to read or save a model to the server. By default, it uses 2744 <tt>jQuery.ajax</tt> to make a RESTful JSON request and returns a 2745 <a href="http://api.jquery.com/jQuery.ajax/#jqXHR">jqXHR</a>. You can override 2746 it in order to use a different persistence strategy, such as WebSockets, 2747 XML transport, or Local Storage. 2748 </p> 2749 2750 <p> 2751 The method signature of <b>Backbone.sync</b> is <tt>sync(method, model, [options])</tt> 2752 </p> 2753 2754 <ul> 2755 <li><b>method</b> – the CRUD method (<tt>"create"</tt>, <tt>"read"</tt>, <tt>"update"</tt>, or <tt>"delete"</tt>)</li> 2756 <li><b>model</b> – the model to be saved (or collection to be read)</li> 2757 <li><b>options</b> – success and error callbacks, and all other jQuery request options</li> 2758 </ul> 2759 2760 <p> 2761 With the default implementation, when <b>Backbone.sync</b> sends up a request to save 2762 a model, its attributes will be passed, serialized as JSON, and sent in the HTTP body 2763 with content-type <tt>application/json</tt>. When returning a JSON response, 2764 send down the attributes of the model that have been changed by the server, and need 2765 to be updated on the client. When responding to a <tt>"read"</tt> request from a collection 2766 (<a href="#Collection-fetch">Collection#fetch</a>), send down an array 2767 of model attribute objects. 2768 </p> 2769 2770 <p> 2771 Whenever a model or collection begins a <b>sync</b> with the server, a 2772 <tt>"request"</tt> event is emitted. If the request completes successfully 2773 you'll get a <tt>"sync"</tt> event, and an <tt>"error"</tt> event if not. 2774 </p> 2775 2776 <p> 2777 The <b>sync</b> function may be overridden globally as <tt>Backbone.sync</tt>, 2778 or at a finer-grained level, by adding a <tt>sync</tt> function to a Backbone 2779 collection or to an individual model. 2780 </p> 2781 2782 <p> 2783 The default <b>sync</b> handler maps CRUD to REST like so: 2784 </p> 2785 2786 <ul> 2787 <li><b>create → POST </b><tt>/collection</tt></li> 2788 <li><b>read → GET </b><tt>/collection[/id]</tt></li> 2789 <li><b>update → PUT </b><tt>/collection/id</tt></li> 2790 <li><b>patch → PATCH </b><tt>/collection/id</tt></li> 2791 <li><b>delete → DELETE </b><tt>/collection/id</tt></li> 2792 </ul> 2793 2794 <p> 2795 As an example, a Rails 4 handler responding to an <tt>"update"</tt> call from 2796 <tt>Backbone</tt> might look like this: 2797 </p> 2798 2799<pre> 2800def update 2801 account = Account.find params[:id] 2802 permitted = params.require(:account).permit(:name, :otherparam) 2803 account.update_attributes permitted 2804 render :json => account 2805end 2806</pre> 2807 2808 <p> 2809 One more tip for integrating Rails versions prior to 3.1 is to disable 2810 the default namespacing for <tt>to_json</tt> calls on models by setting 2811 <tt>ActiveRecord::Base.include_root_in_json = false</tt> 2812 </p> 2813 2814 <p id="Sync-ajax"> 2815 <b class="header">ajax</b><code>Backbone.ajax = function(request) { ... };</code> 2816 <br /> 2817 If you want to use a custom AJAX function, or your endpoint doesn't support 2818 the <a href="http://api.jquery.com/jQuery.ajax/">jQuery.ajax</a> API 2819 and you need to tweak things, you can do so by setting <tt>Backbone.ajax</tt>. 2820 </p> 2821 2822 <p id="Sync-emulateHTTP"> 2823 <b class="header">emulateHTTP</b><code>Backbone.emulateHTTP = true</code> 2824 <br /> 2825 If you want to work with a legacy web server that doesn't support Backbone's 2826 default REST/HTTP approach, you may choose to turn on <tt>Backbone.emulateHTTP</tt>. 2827 Setting this option will fake <tt>PUT</tt>, <tt>PATCH</tt> and <tt>DELETE</tt> requests with 2828 a HTTP <tt>POST</tt>, setting the <tt>X-HTTP-Method-Override</tt> header 2829 with the true method. If <tt>emulateJSON</tt> is also on, the true method 2830 will be passed as an additional <tt>_method</tt> parameter. 2831 </p> 2832 2833<pre> 2834Backbone.emulateHTTP = true; 2835 2836model.save(); // POST to "/collection/id", with "_method=PUT" + header. 2837</pre> 2838 2839 <p id="Sync-emulateJSON"> 2840 <b class="header">emulateJSON</b><code>Backbone.emulateJSON = true</code> 2841 <br /> 2842 If you're working with a legacy web server that can't handle requests 2843 encoded as <tt>application/json</tt>, setting <tt>Backbone.emulateJSON = true;</tt> 2844 will cause the JSON to be serialized under a <tt>model</tt> parameter, and 2845 the request to be made with a <tt>application/x-www-form-urlencoded</tt> 2846 MIME type, as if from an HTML form. 2847 </p> 2848 2849 <h2 id="View">Backbone.View</h2> 2850 2851 <p> 2852 Backbone views are almost more convention than they are code — they 2853 don't determine anything about your HTML or CSS for you, and can be used 2854 with any JavaScript templating library. 2855 The general idea is to organize your interface into logical views, 2856 backed by models, each of which can be updated independently when the 2857 model changes, without having to redraw the page. Instead of digging into 2858 a JSON object, looking up an element in the DOM, and updating the HTML by hand, 2859 you can bind your view's <tt>render</tt> function to the model's <tt>"change"</tt> 2860 event — and now everywhere that 2861 model data is displayed in the UI, it is always immediately up to date. 2862 </p> 2863 2864 <p id="View-extend"> 2865 <b class="header">extend</b><code>Backbone.View.extend(properties, [classProperties])</code> 2866 <br /> 2867 Get started with views by creating a custom view class. You'll want to 2868 override the <a href="#View-render">render</a> function, specify your 2869 declarative <a href="#View-delegateEvents">events</a>, and perhaps the 2870 <tt>tagName</tt>, <tt>className</tt>, or <tt>id</tt> of the View's root 2871 element. 2872 </p> 2873 2874<pre> 2875var DocumentRow = Backbone.View.extend({ 2876 2877 tagName: "li", 2878 2879 className: "document-row", 2880 2881 events: { 2882 "click .icon": "open", 2883 "click .button.edit": "openEditDialog", 2884 "click .button.delete": "destroy" 2885 }, 2886 2887 initialize: function() { 2888 this.listenTo(this.model, "change", this.render); 2889 }, 2890 2891 render: function() { 2892 ... 2893 } 2894 2895}); 2896</pre> 2897 2898 <p> 2899 Properties like <tt>tagName</tt>, <tt>id</tt>, <tt>className</tt>, 2900 <tt>el</tt>, and <tt>events</tt> may also be defined as a function, if 2901 you want to wait to define them until runtime. 2902 </p> 2903 2904 <p id="View-preinitialize"> 2905 <b class="header">preinitialize</b><code>new View([options])</code> 2906 <br /> 2907 For use with views as ES classes. If you define a <b>preinitialize</b> 2908 method, it will be invoked when the view is first created, before any 2909 instantiation logic is run. 2910 </p> 2911 2912<pre> 2913class Document extends Backbone.View { 2914 preinitialize({autoRender}) { 2915 this.autoRender = autoRender; 2916 } 2917 2918 initialize() { 2919 if (this.autoRender) { 2920 this.listenTo(this.model, "change", this.render); 2921 } 2922 } 2923} 2924</pre> 2925 2926 <p id="View-constructor"> 2927 <b class="header">constructor / initialize</b><code>new View([options])</code> 2928 <br /> 2929 There are several special 2930 options that, if passed, will be attached directly to the view: 2931 <tt>model</tt>, <tt>collection</tt>, 2932 <tt>el</tt>, <tt>id</tt>, <tt>className</tt>, <tt>tagName</tt>, <tt>attributes</tt> and <tt>events</tt>. 2933 If the view defines an <b>initialize</b> function, it will be called when 2934 the view is first created. If you'd like to create a view that references 2935 an element <i>already</i> in the DOM, pass in the element as an option: 2936 <tt>new View({el: existingElement})</tt> 2937 </p> 2938 2939<pre> 2940var doc = documents.first(); 2941 2942new DocumentRow({ 2943 model: doc, 2944 id: "document-row-" + doc.id 2945}); 2946</pre> 2947 2948 <p id="View-el"> 2949 <b class="header">el</b><code>view.el</code> 2950 <br /> 2951 All views have a DOM element at all times (the <b>el</b> property), 2952 whether they've already been inserted into the page or not. In this 2953 fashion, views can be rendered at any time, and inserted into the DOM all 2954 at once, in order to get high-performance UI rendering with as few 2955 reflows and repaints as possible. 2956 </p> 2957 2958 <p> 2959 <tt>this.el</tt> can be resolved from a DOM selector string or an Element; 2960 otherwise it will be created from the view's <tt>tagName</tt>, <tt>className</tt>, 2961 <tt>id</tt> and <a href="#View-attributes"><tt>attributes</tt></a> properties. 2962 If none are set, <tt>this.el</tt> is an empty <tt>div</tt>, which is often just 2963 fine. An <b>el</b> reference may also be passed in to the view's constructor. 2964 </p> 2965 2966<pre class="runnable"> 2967var ItemView = Backbone.View.extend({ 2968 tagName: 'li' 2969}); 2970 2971var BodyView = Backbone.View.extend({ 2972 el: 'body' 2973}); 2974 2975var item = new ItemView(); 2976var body = new BodyView(); 2977 2978alert(item.el + ' ' + body.el); 2979</pre> 2980 2981 <p id="View-$el"> 2982 <b class="header">$el</b><code>view.$el</code> 2983 <br /> 2984 A cached jQuery object for the view's element. A handy 2985 reference instead of re-wrapping the DOM element all the time. 2986 </p> 2987 2988<pre> 2989view.$el.show(); 2990 2991listView.$el.append(itemView.el); 2992</pre> 2993 2994 <p id="View-setElement"> 2995 <b class="header">setElement</b><code>view.setElement(element)</code> 2996 <br /> 2997 If you'd like to apply a Backbone view to a different DOM element, use 2998 <b>setElement</b>, which will also create the cached <tt>$el</tt> reference 2999 and move the view's delegated events from the old element to the new one. 3000 </p> 3001 3002 <p id="View-attributes"> 3003 <b class="header">attributes</b><code>view.attributes</code> 3004 <br /> 3005 A hash of attributes that will be set as HTML DOM element attributes on the 3006 view's <tt>el</tt> (id, class, data-properties, etc.), or a function that 3007 returns such a hash. 3008 </p> 3009 3010 <p id="View-dollar"> 3011 <b class="header">$ (jQuery)</b><code>view.$(selector)</code> 3012 <br /> 3013 If jQuery is included on the page, each view has a 3014 <b>$</b> function that runs queries scoped within the view's element. If you use this 3015 scoped jQuery function, you don't have to use model ids as part of your query 3016 to pull out specific elements in a list, and can rely much more on HTML class 3017 attributes. It's equivalent to running: <tt>view.$el.find(selector)</tt> 3018 </p> 3019 3020<pre> 3021ui.Chapter = Backbone.View.extend({ 3022 serialize : function() { 3023 return { 3024 title: this.$(".title").text(), 3025 start: this.$(".start-page").text(), 3026 end: this.$(".end-page").text() 3027 }; 3028 } 3029}); 3030</pre> 3031 3032 <p id="View-template"> 3033 <b class="header">template</b><code>view.template([data])</code> 3034 <br /> 3035 While templating for a view isn't a function provided directly by Backbone, 3036 it's often a nice convention to define a <b>template</b> function on your 3037 views. In this way, when rendering your view, you have convenient access to 3038 instance data. 3039 For example, using Underscore templates: 3040 </p> 3041 3042<pre> 3043var LibraryView = Backbone.View.extend({ 3044 template: _.template(...) 3045}); 3046</pre> 3047 3048 <p id="View-render"> 3049 <b class="header">render</b><code>view.render()</code> 3050 <br /> 3051 The default implementation of <b>render</b> is a no-op. Override this 3052 function with your code that renders the view template from model data, 3053 and updates <tt>this.el</tt> with the new HTML. A good 3054 convention is to <tt>return this</tt> at the end of <b>render</b> to 3055 enable chained calls. 3056 </p> 3057 3058<pre> 3059var Bookmark = Backbone.View.extend({ 3060 template: _.template(...), 3061 render: function() { 3062 this.$el.html(this.template(this.model.attributes)); 3063 return this; 3064 } 3065}); 3066</pre> 3067 3068 <p> 3069 Backbone is agnostic with respect to your preferred method of HTML templating. 3070 Your <b>render</b> function could even munge together an HTML string, or use 3071 <tt>document.createElement</tt> to generate a DOM tree. However, we suggest 3072 choosing a nice JavaScript templating library. 3073 <a href="http://github.com/janl/mustache.js">Mustache.js</a>, 3074 <a href="http://github.com/creationix/haml-js">Haml-js</a>, and 3075 <a href="http://github.com/sstephenson/eco">Eco</a> are all fine alternatives. 3076 Because <a href="http://underscorejs.org/">Underscore.js</a> is already on the page, 3077 <a href="http://underscorejs.org/#template">_.template</a> 3078 is available, and is an excellent choice if you prefer simple 3079 interpolated-JavaScript style templates. 3080 </p> 3081 3082 <p> 3083 Whatever templating strategy you end up with, it's nice if you <i>never</i> 3084 have to put strings of HTML in your JavaScript. At DocumentCloud, we 3085 use <a href="http://documentcloud.github.com/jammit/">Jammit</a> in order 3086 to package up JavaScript templates stored in <tt>/app/views</tt> as part 3087 of our main <tt>core.js</tt> asset package. 3088 </p> 3089 3090 <p id="View-remove"> 3091 <b class="header">remove</b><code>view.remove()</code> 3092 <br /> 3093 Removes a view and its <tt>el</tt> from the DOM, and calls 3094 <a href="#Events-stopListening">stopListening</a> to remove any bound 3095 events that the view has <a href="#Events-listenTo">listenTo</a>'d. 3096 </p> 3097 3098 <p id="View-events"> 3099 <b class="header">events</b><code>view.events or view.events()</code> 3100 <br /> 3101 The <b>events</b> hash (or method) can be used to specify a set of DOM 3102 events that will be bound to methods on your View 3103 through <a href="#View-delegateEvents">delegateEvents</a>. 3104 </p> 3105 3106 <p> 3107 Backbone will automatically attach the event listeners at instantiation 3108 time, right before invoking <a href="#View-constructor">initialize</a>. 3109 </p> 3110 3111<pre> 3112var ENTER_KEY = 13; 3113var InputView = Backbone.View.extend({ 3114 3115 tagName: 'input', 3116 3117 events: { 3118 "keydown" : "keyAction", 3119 }, 3120 3121 render: function() { ... }, 3122 3123 keyAction: function(e) { 3124 if (e.which === ENTER_KEY) { 3125 this.collection.add({text: this.$el.val()}); 3126 } 3127 } 3128}); 3129</pre> 3130 3131 <p id="View-delegateEvents"> 3132 <b class="header">delegateEvents</b><code>delegateEvents([events])</code> 3133 <br /> 3134 Uses jQuery's <tt>on</tt> function to provide declarative callbacks 3135 for DOM events within a view. 3136 If an <b>events</b> hash is not passed directly, uses <tt>this.events</tt> 3137 as the source. Events are written in the format <tt>{"event selector": "callback"}</tt>. 3138 The callback may be either the name of a method on the view, or a direct 3139 function body. 3140 Omitting the <tt>selector</tt> causes the event to be bound to the view's 3141 root element (<tt>this.el</tt>). By default, <tt>delegateEvents</tt> is called 3142 within the View's constructor for you, so if you have a simple <tt>events</tt> 3143 hash, all of your DOM events will always already be connected, and you will 3144 never have to call this function yourself. 3145 </p> 3146 3147 <p> 3148 The <tt>events</tt> property may also be defined as a function that returns 3149 an <b>events</b> hash, to make it easier to programmatically define your 3150 events, as well as inherit them from parent views. 3151 </p> 3152 3153 <p> 3154 Using <b>delegateEvents</b> provides a number of advantages over manually 3155 using jQuery to bind events to child elements during <a href="#View-render">render</a>. All attached 3156 callbacks are bound to the view before being handed off to jQuery, so when 3157 the callbacks are invoked, <tt>this</tt> continues to refer to the view object. When 3158 <b>delegateEvents</b> is run again, perhaps with a different <tt>events</tt> 3159 hash, all callbacks are removed and delegated afresh — useful for 3160 views which need to behave differently when in different modes. 3161 </p> 3162 3163 <p> 3164 A single-event version of <b>delegateEvents</b> is available as <tt>delegate</tt>. 3165 In fact, <b>delegateEvents</b> is simply a multi-event wrapper around <tt>delegate</tt>. 3166 A counterpart to <tt>undelegateEvents</tt> is available as <tt>undelegate</tt>. 3167 </p> 3168 3169 <p> 3170 A view that displays a document in a search result might look 3171 something like this: 3172 </p> 3173 3174<pre> 3175var DocumentView = Backbone.View.extend({ 3176 3177 events: { 3178 "dblclick" : "open", 3179 "click .icon.doc" : "select", 3180 "contextmenu .icon.doc" : "showMenu", 3181 "click .show_notes" : "toggleNotes", 3182 "click .title .lock" : "editAccessLevel", 3183 "mouseover .title .date" : "showTooltip" 3184 }, 3185 3186 render: function() { 3187 this.$el.html(this.template(this.model.attributes)); 3188 return this; 3189 }, 3190 3191 open: function() { 3192 window.open(this.model.get("viewer_url")); 3193 }, 3194 3195 select: function() { 3196 this.model.set({selected: true}); 3197 }, 3198 3199 ... 3200 3201}); 3202</pre> 3203 3204 <p id="View-undelegateEvents"> 3205 <b class="header">undelegateEvents</b><code>undelegateEvents()</code> 3206 <br /> 3207 Removes all of the view's delegated events. Useful if you want to disable 3208 or remove a view from the DOM temporarily. 3209 </p> 3210 3211 <h2 id="Utility">Utility</h2> 3212 3213 <p id="Utility-Backbone-noConflict"> 3214 <b class="header">Backbone.noConflict</b><code>var backbone = Backbone.noConflict();</code> 3215 <br /> 3216 Returns the <tt>Backbone</tt> object back to its original value. You can 3217 use the return value of <tt>Backbone.noConflict()</tt> to keep a local 3218 reference to Backbone. Useful for embedding Backbone on third-party 3219 websites, where you don't want to clobber the existing Backbone. 3220 </p> 3221 3222<pre> 3223var localBackbone = Backbone.noConflict(); 3224var model = localBackbone.Model.extend(...); 3225</pre> 3226 3227 <p id="Utility-Backbone-$"> 3228 <b class="header">Backbone.$</b><code>Backbone.$ = $;</code> 3229 <br /> 3230 If you have multiple copies of <tt>jQuery</tt> on the page, or simply want 3231 to tell Backbone to use a particular object as its DOM / Ajax library, 3232 this is the property for you. 3233 </p> 3234 3235<pre> 3236Backbone.$ = require('jquery'); 3237</pre> 3238 3239 <h2 id="faq">F.A.Q.</h2> 3240 3241 <p id="FAQ-why-backbone"> 3242 <b class="header">Why use Backbone, not [other framework X]?</b> 3243 <br /> 3244 If your eye hasn't already been caught by the adaptability and elan on display 3245 in the above <a href="#examples">list of examples</a>, we can get more specific: 3246 Backbone.js aims to provide the common foundation that data-rich web applications 3247 with ambitious interfaces require — while very deliberately avoiding 3248 painting you into a corner by making any decisions that you're 3249 better equipped to make yourself. 3250 </p> 3251 3252 <ul> 3253 <li> 3254 The focus is on supplying you with 3255 <a href="#Collection-Underscore-Methods">helpful methods to manipulate and 3256 query your data</a>, not on HTML widgets or reinventing the JavaScript 3257 object model. 3258 </li> 3259 <li> 3260 Backbone does not force you to use a single template engine. Views can bind 3261 to HTML constructed in 3262 <a href="http://underscorejs.org/#template">your</a> 3263 <a href="http://guides.rubyonrails.org/layouts_and_rendering.html">favorite</a> 3264 <a href="http://mustache.github.com">way</a>. 3265 </li> 3266 <li> 3267 It's smaller. There are fewer kilobytes for your browser or phone to download, 3268 and less <i>conceptual</i> surface area. You can read and understand 3269 the source in an afternoon. 3270 </li> 3271 <li> 3272 It doesn't depend on stuffing application logic into your HTML. 3273 There's no embedded JavaScript, template logic, or binding hookup code in 3274 <tt>data-</tt> or <tt>ng-</tt> attributes, and no need to invent your own HTML tags. 3275 </li> 3276 <li> 3277 <a href="#Events">Synchronous events</a> are used as the fundamental 3278 building block, not a difficult-to-reason-about run loop, or by constantly 3279 polling and traversing your data structures to hunt for changes. And if 3280 you want a specific event to be asynchronous and aggregated, 3281 <a href="http://underscorejs.org/#debounce">no problem</a>. 3282 </li> 3283 <li> 3284 Backbone scales well, from <a href="http://disqus.com">embedded widgets</a> 3285 to <a href="http://www.usatoday.com">massive apps</a>. 3286 </li> 3287 <li> 3288 Backbone is a library, not a framework, and plays well with others. 3289 You can embed Backbone widgets in Dojo apps without trouble, or use Backbone 3290 models as the data backing for D3 visualizations (to pick two entirely 3291 random examples). 3292 </li> 3293 <li> 3294 "Two-way data-binding" is avoided. While it certainly makes for a nifty 3295 demo, and works for the most basic CRUD, it doesn't tend to be terribly 3296 useful in your real-world app. Sometimes you want to update on 3297 every keypress, sometimes on blur, sometimes when the panel is closed, 3298 and sometimes when the "save" button is clicked. In almost all cases, simply 3299 serializing the form to JSON is faster and easier. All that aside, if your 3300 heart is set, <a href="http://rivetsjs.com">go</a> 3301 <a href="http://nytimes.github.com/backbone.stickit/">for it</a>. 3302 </li> 3303 <li> 3304 There's no built-in performance penalty for choosing to structure your 3305 code with Backbone. And if you do want to optimize further, thin models and 3306 templates with flexible granularity make it easy to squeeze every last 3307 drop of potential performance out of, say, IE8. 3308 </li> 3309 </ul> 3310 3311 <p id="FAQ-tim-toady"> 3312 <b class="header">There's More Than One Way To Do It</b> 3313 <br /> 3314 It's common for folks just getting started to treat the examples listed 3315 on this page as some sort of gospel truth. In fact, Backbone.js is intended 3316 to be fairly agnostic about many common patterns in client-side code. 3317 For example... 3318 </p> 3319 3320 <p> 3321 <b>References between Models and Views</b> can be handled several ways. 3322 Some people like to have direct pointers, where views correspond 1:1 with 3323 models (<tt>model.view</tt> and <tt>view.model</tt>). Others prefer to have intermediate 3324 "controller" objects that orchestrate the creation and organization of 3325 views into a hierarchy. Others still prefer the evented approach, and always 3326 fire events instead of calling methods directly. All of these styles work well. 3327 </p> 3328 3329 <p> 3330 <b>Batch operations</b> on Models are common, but often best handled differently 3331 depending on your server-side setup. Some folks don't mind making individual 3332 Ajax requests. Others create explicit resources for RESTful batch operations: 3333 <tt>/notes/batch/destroy?ids=1,2,3,4</tt>. Others tunnel REST over JSON, with the 3334 creation of "changeset" requests: 3335 </p> 3336 3337<pre> 3338 { 3339 "create": [array of models to create] 3340 "update": [array of models to update] 3341 "destroy": [array of model ids to destroy] 3342 } 3343</pre> 3344 3345 <p> 3346 <b>Feel free to define your own events.</b> <a href="#Events">Backbone.Events</a> 3347 is designed so that you can mix it in to any JavaScript object or prototype. 3348 Since you can use any string as an event, it's often handy to bind 3349 and trigger your own custom events: <tt>model.on("selected:true")</tt> or 3350 <tt>model.on("editing")</tt> 3351 </p> 3352 3353 <p> 3354 <b>Render the UI</b> as you see fit. Backbone is agnostic as to whether you 3355 use <a href="http://underscorejs.org/#template">Underscore templates</a>, 3356 <a href="https://github.com/janl/mustache.js">Mustache.js</a>, direct DOM 3357 manipulation, server-side rendered snippets of HTML, or 3358 <a href="http://jqueryui.com/">jQuery UI</a> in your <tt>render</tt> function. 3359 Sometimes you'll create a view for each model ... sometimes you'll have a 3360 view that renders thousands of models at once, in a tight loop. Both can be 3361 appropriate in the same app, depending on the quantity of data involved, 3362 and the complexity of the UI. 3363 </p> 3364 3365 <p id="FAQ-nested"> 3366 <b class="header">Nested Models & Collections</b> 3367 <br /> 3368 It's common to nest collections inside of models with Backbone. For example, 3369 consider a <tt>Mailbox</tt> model that contains many <tt>Message</tt> models. 3370 One nice pattern for handling this is have a <tt>this.messages</tt> collection 3371 for each mailbox, enabling the lazy-loading of messages, when the mailbox 3372 is first opened ... perhaps with <tt>MessageList</tt> views listening for 3373 <tt>"add"</tt> and <tt>"remove"</tt> events. 3374 </p> 3375 3376<pre> 3377var Mailbox = Backbone.Model.extend({ 3378 3379 initialize: function() { 3380 this.messages = new Messages; 3381 this.messages.url = '/mailbox/' + this.id + '/messages'; 3382 this.messages.on("reset", this.updateCounts); 3383 }, 3384 3385 ... 3386 3387}); 3388 3389var inbox = new Mailbox; 3390 3391// And then, when the Inbox is opened: 3392 3393inbox.messages.fetch({reset: true}); 3394</pre> 3395 3396 <p> 3397 If you're looking for something more opinionated, there are a number of 3398 Backbone plugins that add sophisticated associations among models, 3399 <a href="https://github.com/jashkenas/backbone/wiki/Extensions%2C-Plugins%2C-Resources">available on the wiki</a>. 3400 </p> 3401 3402 <p> 3403 Backbone doesn't include direct support for nested models and collections 3404 or "has many" associations because there are a number 3405 of good patterns for modeling structured data on the client side, and 3406 <i>Backbone should provide the foundation for implementing any of them.</i> 3407 You may want to… 3408 </p> 3409 3410 <ul> 3411 <li> 3412 Mirror an SQL database's structure, or the structure of a NoSQL database. 3413 </li> 3414 <li> 3415 Use models with arrays of "foreign key" ids, and join to top level 3416 collections (a-la tables). 3417 </li> 3418 <li> 3419 For associations that are numerous, use a range of ids instead of an 3420 explicit list. 3421 </li> 3422 <li> 3423 Avoid ids, and use direct references, creating a partial object graph 3424 representing your data set. 3425 </li> 3426 <li> 3427 Lazily load joined models from the server, or lazily deserialize nested 3428 models from JSON documents. 3429 </li> 3430 </ul> 3431 3432 <p id="FAQ-bootstrap"> 3433 <b class="header">Loading Bootstrapped Models</b> 3434 <br /> 3435 When your app first loads, it's common to have a set of initial models that 3436 you know you're going to need, in order to render the page. Instead of 3437 firing an extra AJAX request to <a href="#Collection-fetch">fetch</a> them, 3438 a nicer pattern is to have their data already bootstrapped into the page. 3439 You can then use <a href="#Collection-reset">reset</a> to populate your 3440 collections with the initial data. At DocumentCloud, in the 3441 <a href="http://en.wikipedia.org/wiki/ERuby">ERB</a> template for the 3442 workspace, we do something along these lines: 3443 </p> 3444 3445<pre> 3446<script> 3447 var accounts = new Backbone.Collection; 3448 accounts.reset(<%= @accounts.to_json %>); 3449 var projects = new Backbone.Collection; 3450 projects.reset(<%= @projects.to_json(:collaborators => true) %>); 3451</script> 3452</pre> 3453 3454 <p>You have to <a href="http://mathiasbynens.be/notes/etago">escape</a> 3455 <tt></</tt> within the JSON string, to prevent JavaScript injection 3456 attacks. 3457 3458 <p id="FAQ-extending"> 3459 <b class="header">Extending Backbone</b> 3460 <br /> 3461 Many JavaScript libraries are meant to be insular and self-enclosed, 3462 where you interact with them by calling their public API, but never peek 3463 inside at the guts. Backbone.js is <i>not</i> that kind of library. 3464 </p> 3465 3466 <p> 3467 Because it serves as a foundation for your application, you're meant to 3468 extend and enhance it in the ways you see fit — the entire source 3469 code is <a href="docs/backbone.html">annotated</a> to make this easier 3470 for you. You'll find that there's very little there apart from core 3471 functions, and most of those can be overridden or augmented should you find 3472 the need. If you catch yourself adding methods to <tt>Backbone.Model.prototype</tt>, 3473 or creating your own base subclass, don't worry — that's how things are 3474 supposed to work. 3475 </p> 3476 3477 <p id="FAQ-mvc"> 3478 <b class="header">How does Backbone relate to "traditional" MVC?</b> 3479 <br /> 3480 Different implementations of the 3481 <a href="http://en.wikipedia.org/wiki/Model–View–Controller">Model-View-Controller</a> 3482 pattern tend to disagree about the definition of a controller. If it helps any, in 3483 Backbone, the <a href="#View">View</a> class can also be thought of as a 3484 kind of controller, dispatching events that originate from the UI, with 3485 the HTML template serving as the true view. We call it a View because it 3486 represents a logical chunk of UI, responsible for the contents of a single 3487 DOM element. 3488 </p> 3489 3490 <p> 3491 Comparing the overall structure of Backbone to a server-side MVC framework 3492 like <b>Rails</b>, the pieces line up like so: 3493 </p> 3494 3495 <ul> 3496 <li> 3497 <b>Backbone.Model</b> – Like a Rails model minus the class 3498 methods. Wraps a row of data in business logic. 3499 </li> 3500 <li> 3501 <b>Backbone.Collection</b> – A group of models on the client-side, 3502 with sorting/filtering/aggregation logic. 3503 </li> 3504 <li> 3505 <b>Backbone.Router</b> – Rails <tt>routes.rb</tt> + Rails controller 3506 actions. Maps URLs to functions. 3507 </li> 3508 <li> 3509 <b>Backbone.View</b> – A logical, re-usable piece of UI. Often, 3510 but not always, associated with a model. 3511 </li> 3512 <li> 3513 <b>Client-side Templates</b> – Rails <tt>.html.erb</tt> views, 3514 rendering a chunk of HTML. 3515 </li> 3516 </ul> 3517 3518 <p id="FAQ-this"> 3519 <b class="header">Binding "this"</b> 3520 <br /> 3521 Perhaps the single most common JavaScript "gotcha" is the fact that when 3522 you pass a function as a callback, its value for <tt>this</tt> is lost. 3523 When dealing with <a href="#Events">events</a> and callbacks in Backbone, 3524 you'll often find it useful to rely on <a href="#Events-listenTo">listenTo</a> 3525 or the optional <tt>context</tt> argument that many of Underscore 3526 and Backbone's methods use to specify the <tt>this</tt> 3527 that will be used when the callback is later invoked. (See 3528 <a href="http://underscorejs.org/#each">_.each</a>, 3529 <a href="http://underscorejs.org/#map">_.map</a>, and 3530 <a href="#Events-on">object.on</a>, to name a few). 3531 <a href="#View-delegateEvents">View events</a> are automatically bound to 3532 the view's context for you. 3533 You may also find it helpful to use 3534 <a href="http://underscorejs.org/#bind">_.bind</a> and 3535 <a href="http://underscorejs.org/#bindAll">_.bindAll</a> 3536 from Underscore.js. 3537 </p> 3538 3539<pre> 3540var MessageList = Backbone.View.extend({ 3541 3542 initialize: function() { 3543 var messages = this.collection; 3544 messages.on("reset", this.render, this); 3545 messages.on("add", this.addMessage, this); 3546 messages.on("remove", this.removeMessage, this); 3547 3548 messsages.each(this.addMessage, this); 3549 } 3550 3551}); 3552 3553// Later, in the app... 3554 3555Inbox.messages.add(newMessage); 3556</pre> 3557 3558 <p id="FAQ-rails"> 3559 <b class="header">Working with Rails</b> 3560 <br /> 3561 Backbone.js was originally extracted from 3562 <a href="http://www.documentcloud.org">a Rails application</a>; getting 3563 your client-side (Backbone) Models to sync correctly with your server-side 3564 (Rails) Models is painless, but there are still a few things to be aware of. 3565 </p> 3566 3567 <p> 3568 By default, Rails versions prior to 3.1 add an extra layer of wrapping 3569 around the JSON representation of models. You can disable this wrapping 3570 by setting: 3571 </p> 3572 3573<pre> 3574ActiveRecord::Base.include_root_in_json = false 3575</pre> 3576 3577 <p> 3578 ... in your configuration. Otherwise, override 3579 <a href="#Model-parse">parse</a> to pull model attributes out of the 3580 wrapper. Similarly, Backbone PUTs and POSTs direct JSON representations 3581 of models, where by default Rails expects namespaced attributes. You can 3582 have your controllers filter attributes directly from <tt>params</tt>, or 3583 you can override <a href="#Model-toJSON">toJSON</a> in Backbone to add 3584 the extra wrapping Rails expects. 3585 </p> 3586 3587 <h2 id="examples">Examples</h2> 3588 3589 <p> 3590 The list of examples that follows, while long, is not exhaustive — nor in 3591 any way current. If you've worked on an app that uses Backbone, please 3592 add it to the <a href="https://github.com/jashkenas/backbone/wiki/Projects-and-Companies-using-Backbone">wiki page of Backbone apps</a>. 3593 </p> 3594 3595 <p id="examples-todos"> 3596 <a href="http://jgn.me/">Jérôme Gravel-Niquet</a> has contributed a 3597 <a href="examples/todos/index.html">Todo List application</a> 3598 that is bundled in the repository as Backbone example. If you're wondering 3599 where to get started with Backbone in general, take a moment to 3600 <a href="docs/todos.html">read through the annotated source</a>. The app uses a 3601 <a href="http://github.com/jeromegn/Backbone.localStorage">LocalStorage adapter</a> 3602 to transparently save all of your todos within your browser, instead of 3603 sending them to a server. Jérôme also has a version hosted at 3604 <a href="http://localtodos.com/">localtodos.com</a>. 3605 </p> 3606 3607 <div style="text-align: center;"> 3608 <a href="examples/todos/index.html"> 3609 <img width="400" height="427" data-original="docs/images/todos.jpg" alt="Todos" class="example_retina" /> 3610 </a> 3611 </div> 3612 3613 <h2 id="examples-documentcloud">DocumentCloud</h2> 3614 3615 <p> 3616 The <a href="http://www.documentcloud.org/public/#search/">DocumentCloud workspace</a> 3617 is built on Backbone.js, with <i>Documents</i>, <i>Projects</i>, 3618 <i>Notes</i>, and <i>Accounts</i> all as Backbone models and collections. 3619 If you're interested in history — both Underscore.js and Backbone.js 3620 were originally extracted from the DocumentCloud codebase, and packaged 3621 into standalone JS libraries. 3622 </p> 3623 3624 <div style="text-align: center;"> 3625 <a href="http://www.documentcloud.org/public/#search/"> 3626 <img width="550" height="453" data-original="docs/images/dc-workspace.jpg" alt="DocumentCloud Workspace" class="example_retina" /> 3627 </a> 3628 </div> 3629 3630 <h2 id="examples-usa-today">USA Today</h2> 3631 3632 <p> 3633 <a href="http://usatoday.com">USA Today</a> takes advantage of the modularity of 3634 Backbone's data/model lifecycle — which makes it simple to create, inherit, 3635 isolate, and link application objects — to keep the codebase both manageable and efficient. 3636 The new website also makes heavy use of the Backbone Router to control the 3637 page for both pushState-capable and legacy browsers. 3638 Finally, the team took advantage of Backbone's Event module to create a 3639 PubSub API that allows third parties and analytics packages to hook into the 3640 heart of the app. 3641 </p> 3642 3643 <div style="text-align: center;"> 3644 <a href="http://usatoday.com"> 3645 <img width="550" height="532" data-original="docs/images/usa-today.jpg" alt="USA Today" class="example_retina" /> 3646 </a> 3647 </div> 3648 3649 <h2 id="examples-rdio">Rdio</h2> 3650 3651 <p> 3652 <a href="http://rdio.com/new">New Rdio</a> was developed from the ground 3653 up with a component based framework based on Backbone.js. Every component 3654 on the screen is dynamically loaded and rendered, with data provided by the 3655 <a href="http://developer.rdio.com/">Rdio API</a>. When changes are pushed, 3656 every component can update itself without reloading the page or interrupting 3657 the user's music. All of this relies on Backbone's views and models, 3658 and all URL routing is handled by Backbone's Router. When data changes are 3659 signaled in realtime, Backbone's Events notify the interested components 3660 in the data changes. Backbone forms the core of the new, dynamic, realtime 3661 Rdio web and <i>desktop</i> applications. 3662 </p> 3663 3664 <div style="text-align: center;"> 3665 <a href="http://rdio.com/new"> 3666 <img width="550" height="344" data-original="docs/images/rdio.jpg" alt="Rdio" class="example_retina" /> 3667 </a> 3668 </div> 3669 3670 <h2 id="examples-hulu">Hulu</h2> 3671 3672 <p> 3673 <a href="http://hulu.com">Hulu</a> used Backbone.js to build its next 3674 generation online video experience. With Backbone as a foundation, the 3675 web interface was rewritten from scratch so that all page content can 3676 be loaded dynamically with smooth transitions as you navigate. 3677 Backbone makes it easy to move through the app quickly without the 3678 reloading of scripts and embedded videos, while also offering models and 3679 collections for additional data manipulation support. 3680 </p> 3681 3682 <div style="text-align: center;"> 3683 <a href="http://hulu.com"> 3684 <img width="550" height="449" data-original="docs/images/hulu.jpg" alt="Hulu" class="example_retina" /> 3685 </a> 3686 </div> 3687 3688 <h2 id="examples-quartz">Quartz</h2> 3689 3690 <p> 3691 <a href="http://qz.com">Quartz</a> sees itself as a digitally native news 3692 outlet for the new 3693 global economy. Because Quartz believes in the future of open, 3694 cross-platform web applications, they selected Backbone and Underscore 3695 to fetch, sort, store, and display content from a custom WordPress 3696 API. Although <a href="http://qz.com">qz.com</a> uses responsive design 3697 for phone, tablet, and 3698 desktop browsers, it also takes advantage of Backbone events and views 3699 to render device-specific templates in some cases. 3700 </p> 3701 3702 <div style="text-align: center;"> 3703 <a href="http://qz.com"> 3704 <img width="510" height="360" data-original="docs/images/quartz.jpg" alt="Quartz" class="example_retina" /> 3705 </a> 3706 </div> 3707 3708 <h2 id="examples-earth">Earth</h2> 3709 3710 <p> 3711 <a href="http://earth.nullschool.net">Earth.nullschool.net</a> displays real-time weather 3712 conditions on an interactive animated globe, and Backbone provides the 3713 foundation upon which all of the site's components are built. Despite the 3714 presence of several other JavaScript libraries, Backbone's non-opinionated 3715 design made it effortless to mix-in the <a href="#Events">Events</a> functionality used for 3716 distributing state changes throughout the page. When the decision was made 3717 to switch to Backbone, large blocks of custom logic simply disappeared. 3718 </p> 3719 3720 <div style="text-align: center;"> 3721 <a href="http://earth.nullschool.net"> 3722 <img width="545" height="583" data-original="docs/images/earth.jpg" alt="Earth" class="example_retina" /> 3723 </a> 3724 </div> 3725 3726 <h2 id="examples-vox">Vox</h2> 3727 3728 <p> 3729 Vox Media, the publisher of 3730 <a href="http://www.sbnation.com/">SB Nation</a>, 3731 <a href="http://www.theverge.com/">The Verge</a>, 3732 <a href="http://www.polygon.com/">Polygon</a>, 3733 <a href="http://www.eater.com/">Eater</a>, 3734 <a href="http://www.racked.com/">Racked</a>, 3735 <a href="http://www.curbed.com/">Curbed</a>, and 3736 <a href="http://www.vox.com/">Vox.com</a>, uses Backbone throughout 3737 <a href="http://techcrunch.com/2012/05/07/a-closer-look-at-chorus-the-next-generation-publishing-platform-that-runs-vox-media/">Chorus</a>, 3738 its home-grown publishing platform. Backbone powers the 3739 <a href="http://product.voxmedia.com/post/25113965826/introducing-syllabus-vox-medias-s3-powered-liveblog">liveblogging platform</a> 3740 and <a href="http://product.voxmedia.com/2013/11/11/5426878/using-backbone-js-for-sanity-and-stability">commenting system</a> 3741 used across all Vox Media properties; Coverage, an internal editorial coordination tool; 3742 <a href="http://www.sbnation.com/college-basketball/2014/4/7/5592112/kentucky-vs-uconn-2014-ncaa-tournament-championship-live-chat">SB Nation Live</a>, 3743 a live event coverage and chat tool; and 3744 <a href="http://www.vox.com/cards/ukraine-everything-you-need-to-know/what-is-the-ukraine-crisis">Vox Cards</a>, 3745 Vox.com's highlighter-and-index-card inspired app for providing context about the news. 3746 </p> 3747 3748 <div style="text-align: center;"> 3749 <a href="http://vox.com"> 3750 <img width="550" height="402" data-original="docs/images/vox.jpg" alt="Vox" class="example_retina" /> 3751 </a> 3752 </div> 3753 3754 <h2 id="examples-gawker">Gawker Media</h2> 3755 3756 <p> 3757 <a href="http://kinja.com">Kinja</a> is Gawker Media's publishing platform designed 3758 to create great stories by breaking down the lines between the traditional 3759 roles of content creators and consumers. Everyone — editors, readers, 3760 marketers — have access to the same tools to engage in passionate discussion 3761 and pursue the truth of the story. Sharing, recommending, and following within the 3762 Kinja ecosystem allows for improved information discovery across all the sites. 3763 </p> 3764 <p> 3765 Kinja is the platform behind 3766 <a href="http://gawker.com/">Gawker</a>, 3767 <a href="http://gizmodo.com/">Gizmodo</a>, 3768 <a href="http://lifehacker.com/">Lifehacker</a>, 3769 <a href="http://io9.com/">io9</a> and other Gawker Media 3770 blogs. Backbone.js underlies the front-end application code that powers 3771 everything from user authentication to post authoring, commenting, and even serving 3772 ads. The JavaScript stack includes 3773 <a href="http://underscorejs.org/">Underscore.js</a> and 3774 <a href="http://jquery.com/">jQuery</a>, with some plugins, 3775 all loaded with 3776 <a href="http://requirejs.org/">RequireJS</a>. Closure templates are shared between the 3777 <a href="http://www.playframework.com/">Play! Framework</a> based Scala application and Backbone views, and the responsive layout 3778 is done with the 3779 <a href="http://foundation.zurb.com/">Foundation</a> framework using 3780 <a href="http://sass-lang.com/">SASS</a>. 3781 </p> 3782 3783 <div style="text-align: center;"> 3784 <a href="http://gawker.com"> 3785 <img width="558" height="473" data-original="docs/images/gawker.jpg" alt="Gawker" class="example_retina" /> 3786 </a> 3787 </div> 3788 3789 <h2 id="examples-flow">Flow</h2> 3790 3791 <p> 3792 <a href="http://www.metalabdesign.com/">MetaLab</a> used Backbone.js to create 3793 <a href="http://www.getflow.com/">Flow</a>, a task management app for teams. The 3794 workspace relies on Backbone.js to construct task views, activities, accounts, 3795 folders, projects, and tags. You can see the internals under <tt>window.Flow</tt>. 3796 </p> 3797 3798 <div style="text-align: center;"> 3799 <a href="http://www.getflow.com/"> 3800 <img width="550" height="416" data-original="docs/images/flow.jpg" alt="Flow" class="example_retina" /> 3801 </a> 3802 </div> 3803 3804 <h2 id="examples-gilt">Gilt Groupe</h2> 3805 3806 <p> 3807 <a href="http://gilt.com">Gilt Groupe</a> uses Backbone.js to build multiple 3808 applications across their family of sites. 3809 <a href="http://m.gilt.com">Gilt's mobile website</a> uses Backbone and 3810 <a href="http://zeptojs.com">Zepto.js</a> to create a blazing-fast 3811 shopping experience for users on-the-go, while 3812 <a href="http://live.gilt.com">Gilt Live</a> combines Backbone with 3813 WebSockets to display the items that customers are buying in real-time. Gilt's search 3814 functionality also uses Backbone to filter and sort products efficiently 3815 by moving those actions to the client-side. 3816 </p> 3817 3818 <div style="text-align: center;"> 3819 <a href="http://www.gilt.com/"> 3820 <img width="550" height="444" data-original="docs/images/gilt.jpg" alt="Gilt Groupe" class="example_retina" /> 3821 </a> 3822 </div> 3823 3824 <h2 id="examples-enigma">Enigma</h2> 3825 3826 <p> 3827 <a href="http://enigma.io">Enigma</a> is a portal amassing the largest 3828 collection of public data produced by governments, universities, companies, 3829 and organizations. Enigma uses Backbone Models and Collections to represent 3830 complex data structures; and Backbone's Router gives Enigma users unique URLs for 3831 application states, allowing them to navigate quickly through the site while 3832 maintaining the ability to bookmark pages and navigate forward and backward 3833 through their session. 3834 </p> 3835 3836 <div style="text-align: center;"> 3837 <a href="http://www.enigma.io/"> 3838 <img width="550" height="409" data-original="docs/images/enigma.jpg" alt="Enigma" class="example_retina" /> 3839 </a> 3840 </div> 3841 3842 <h2 id="examples-newsblur">NewsBlur</h2> 3843 3844 <p> 3845 <a href="http://www.newsblur.com">NewsBlur</a> is an RSS feed reader and 3846 social news network with a fast and responsive UI that feels like a 3847 native desktop app. Backbone.js was selected for 3848 <a href="http://www.ofbrooklyn.com/2012/11/13/backbonification-migrating-javascript-to-backbone/">a major rewrite and transition from spaghetti code</a> 3849 because of its powerful yet simple feature set, easy integration, and large 3850 community. If you want to poke around under the hood, NewsBlur is also entirely 3851 <a href="http://github.com/samuelclay/NewsBlur">open-source</a>. 3852 </p> 3853 3854 <div style="text-align: center;"> 3855 <a href="http://newsblur.com"> 3856 <img width="510" height="340" data-original="docs/images/newsblur.jpg" alt="Newsblur" class="example_retina" /> 3857 </a> 3858 </div> 3859 3860 <h2 id="examples-wordpress">WordPress.com</h2> 3861 3862 <p> 3863 <a href="http://wordpress.com/">WordPress.com</a> is the software-as-a-service 3864 version of <a href="http://wordpress.org">WordPress</a>. It uses Backbone.js 3865 Models, Collections, and Views in its 3866 <a href="http://en.blog.wordpress.com/2012/05/25/notifications-refreshed/">Notifications system</a>. Backbone.js was selected 3867 because it was easy to fit into the structure of the application, not the 3868 other way around. <a href="http://automattic.com">Automattic</a> 3869 (the company behind WordPress.com) is integrating Backbone.js into the 3870 Stats tab and other features throughout the homepage. 3871 </p> 3872 3873 <div style="text-align: center;"> 3874 <a href="http://wordpress.com/"> 3875 <img width="550" height="387" data-original="docs/images/wpcom-notifications.jpg" alt="WordPress.com Notifications" 3876 title="WordPress.com Notifications" class="example_retina" /> 3877 </a> 3878 </div> 3879 3880 <h2 id="examples-foursquare">Foursquare</h2> 3881 3882 <p> 3883 Foursquare is a fun little startup that helps you meet up with friends, 3884 discover new places, and save money. Backbone Models are heavily used in 3885 the core JavaScript API layer and Views power many popular features like 3886 the <a href="https://foursquare.com">homepage map</a> and 3887 <a href="https://foursquare.com/seriouseats/list/the-best-doughnuts-in-ny">lists</a>. 3888 </p> 3889 3890 <div style="text-align: center;"> 3891 <a href="http://foursquare.com"> 3892 <img width="550" height="427" data-original="docs/images/foursquare.jpg" alt="Foursquare" class="example_retina" /> 3893 </a> 3894 </div> 3895 3896 <h2 id="examples-bitbucket">Bitbucket</h2> 3897 3898 <p> 3899 <a href="http://www.bitbucket.org">Bitbucket</a> is a free source code hosting 3900 service for Git and Mercurial. Through its models and collections, 3901 Backbone.js has proved valuable in supporting Bitbucket's 3902 <a href="https://api.bitbucket.org">REST API</a>, as well as newer 3903 components such as in-line code comments and approvals for pull requests. 3904 Mustache templates provide server and client-side rendering, while a custom 3905 <a href="https://developers.google.com/closure/library/">Google Closure</a> 3906 inspired life-cycle for widgets allows Bitbucket to decorate existing DOM 3907 trees and insert new ones. 3908 </p> 3909 3910 <div style="text-align: center;"> 3911 <a href="http://www.bitbucket.org"> 3912 <img width="550" height="356" data-original="docs/images/bitbucket.jpg" alt="Bitbucket" class="example_retina" /> 3913 </a> 3914 </div> 3915 3916 <h2 id="examples-disqus">Disqus</h2> 3917 3918 <p> 3919 <a href="http://www.disqus.com">Disqus</a> chose Backbone.js to power the 3920 latest version of their commenting widget. Backbone’s small 3921 footprint and easy extensibility made it the right choice for Disqus’ 3922 distributed web application, which is hosted entirely inside an iframe and 3923 served on thousands of large web properties, including IGN, Wired, CNN, MLB, and more. 3924 </p> 3925 3926 <div style="text-align: center;"> 3927 <a href="http://www.disqus.com"> 3928 <img width="550" height="454" data-original="docs/images/disqus.jpg" alt="Disqus" class="example_retina" /> 3929 </a> 3930 </div> 3931 3932 <h2 id="examples-delicious">Delicious</h2> 3933 3934 <p> 3935 <a href="https://delicious.com/">Delicious</a> is a social bookmarking 3936 platform making it easy to save, sort, and store bookmarks from across 3937 the web. Delicious uses <a href="http://chaplinjs.org">Chaplin.js</a>, 3938 Backbone.js and AppCache to build a full-featured MVC web app. 3939 The use of Backbone helped the website and 3940 <a href="http://delicious.com/tools">mobile apps</a> share a 3941 single API service, and the reuse of the model tier made it significantly 3942 easier to share code during the recent Delicious redesign. 3943 </p> 3944 3945 <div style="text-align: center;"> 3946 <a href="http://www.delicious.com"> 3947 <img width="510" height="321" data-original="docs/images/delicious.jpg" alt="Delicious" class="example_retina" /> 3948 </a> 3949 </div> 3950 3951 <h2 id="examples-khan-academy">Khan Academy</h2> 3952 3953 <p> 3954 <a href="http://www.khanacademy.org">Khan Academy</a> is on a mission to 3955 provide a free world-class education to anyone anywhere. With thousands of 3956 videos, hundreds of JavaScript-driven exercises, and big plans for the 3957 future, Khan Academy uses Backbone to keep frontend code modular and organized. 3958 User profiles and goal setting are implemented with Backbone, 3959 <a href="http://jquery.com/">jQuery</a> and 3960 <a href="http://handlebarsjs.com/">Handlebars</a>, and most new feature 3961 work is being pushed to the client side, greatly increasing the quality of 3962 <a href="https://github.com/Khan/khan-api/">the API</a>. 3963 </p> 3964 3965 <div style="text-align: center;"> 3966 <a href="http://www.khanacademy.org"> 3967 <img width="550" height="454" data-original="docs/images/khan-academy.jpg" alt="Khan Academy" class="example_retina" /> 3968 </a> 3969 </div> 3970 3971 <h2 id="examples-irccloud">IRCCloud</h2> 3972 3973 <p> 3974 <a href="http://irccloud.com/">IRCCloud</a> 3975 is an always-connected IRC client that you use in your 3976 browser — often leaving it open all day in a tab. 3977 The sleek web interface communicates with an 3978 Erlang backend via websockets and the 3979 <a href="https://github.com/irccloud/irccloud-tools/wiki/API-Overview">IRCCloud API</a>. 3980 It makes heavy use of Backbone.js events, models, views and routing to keep 3981 your IRC conversations flowing in real time. 3982 </p> 3983 3984 <div style="text-align: center;"> 3985 <a href="http://irccloud.com/"> 3986 <img width="550" height="392" data-original="docs/images/irccloud.png" alt="IRCCloud" class="example_image" /> 3987 </a> 3988 </div> 3989 3990 <h2 id="examples-pitchfork">Pitchfork</h2> 3991 3992 <p> 3993 <a href="http://pitchfork.com/">Pitchfork</a> uses Backbone.js to power 3994 its site-wide audio player, <a href="http://pitchfork.com/tv/">Pitchfork.tv</a>, 3995 location routing, a write-thru page fragment cache, and more. Backbone.js 3996 (and <a href="http://underscorejs.org/">Underscore.js</a>) helps the team 3997 create clean and modular components, 3998 move very quickly, and focus on the site, not the spaghetti. 3999 </p> 4000 4001 <div style="text-align: center;"> 4002 <a href="http://pitchfork.com/"> 4003 <img width="550" height="428" data-original="docs/images/pitchfork.jpg" alt="Pitchfork" class="example_retina" /> 4004 </a> 4005 </div> 4006 4007 <h2 id="examples-spin">Spin</h2> 4008 4009 <p> 4010 <a href="http://spin.com/">Spin</a> pulls in the 4011 <a href="http://www.spin.com/news">latest news stories</a> from 4012 their internal API onto their site using Backbone models and collections, and a 4013 custom <tt>sync</tt> method. Because the music should never stop playing, 4014 even as you click through to different "pages", Spin uses a Backbone router 4015 for navigation within the site. 4016 </p> 4017 4018 <div style="text-align: center;"> 4019 <a href="http://spin.com/"> 4020 <img width="550" height="543" data-original="docs/images/spin.jpg" alt="Spin" class="example_retina" /> 4021 </a> 4022 </div> 4023 4024 <h2 id="examples-zocdoc">ZocDoc</h2> 4025 4026 <p> 4027 <a href="http://www.zocdoc.com">ZocDoc</a> helps patients 4028 find local, in-network doctors and dentists, see their real-time 4029 availability, and instantly book appointments. 4030 On the public side, the webapp uses Backbone.js to handle client-side state and rendering in 4031 <a href="http://www.zocdoc.com/primary-care-doctors/los-angeles-13122pm">search pages</a> 4032 and <a href="http://www.zocdoc.com/doctor/nathan-hashimoto-md-58078">doctor profiles</a>. 4033 In addition, the new version of the doctor-facing part of the website is a 4034 large single-page application that 4035 benefits from Backbone's structure and modularity. ZocDoc's Backbone 4036 classes are tested with 4037 <a href="https://jasmine.github.io/">Jasmine</a>, and delivered 4038 to the end user with 4039 <a href="http://getcassette.net/">Cassette</a>. 4040 </p> 4041 4042 <div style="text-align: center;"> 4043 <a href="http://www.zocdoc.com"> 4044 <img width="510" height="464" data-original="docs/images/zocdoc.jpg" alt="ZocDoc" class="example_retina" /> 4045 </a> 4046 </div> 4047 4048 <h2 id="examples-walmart">Walmart Mobile</h2> 4049 4050 <p> 4051 <a href="http://www.walmart.com/">Walmart</a> used Backbone.js to create the new version 4052 of <a href="http://mobile.walmart.com/">their mobile web application</a> and 4053 created two new frameworks in the process. 4054 <a href="http://walmartlabs.github.com/thorax/">Thorax</a> provides mixins, inheritable 4055 events, as well as model and collection view bindings that integrate directly with 4056 <a href="http://handlebarsjs.com/">Handlebars</a> templates. 4057 <a href="http://walmartlabs.github.com/lumbar/">Lumbar</a> allows the application to be 4058 split into modules which can be loaded on demand, and creates platform specific builds 4059 for the portions of the web application that are embedded in Walmart's native Android 4060 and iOS applications. 4061 </p> 4062 4063 <div style="text-align: center;"> 4064 <a href="http://mobile.walmart.com/r/phoenix"> 4065 <img width="256" height="534" data-original="docs/images/walmart-mobile.png" alt="Walmart Mobile" class="example_image" /> 4066 </a> 4067 </div> 4068 4069 <h2 id="examples-groupon">Groupon Now!</h2> 4070 4071 <p> 4072 <a href="http://www.groupon.com/now">Groupon Now!</a> helps you find 4073 local deals that you can buy and use right now. When first developing 4074 the product, the team decided it would be AJAX heavy with smooth transitions 4075 between sections instead of full refreshes, but still needed to be fully 4076 linkable and shareable. Despite never having used Backbone before, the 4077 learning curve was incredibly quick — a prototype was hacked out in an 4078 afternoon, and the team was able to ship the product in two weeks. 4079 Because the source is minimal and understandable, it was easy to 4080 add several Backbone extensions for Groupon Now!: changing the router 4081 to handle URLs with querystring parameters, and adding a simple 4082 in-memory store for caching repeated requests for the same data. 4083 </p> 4084 4085 <div style="text-align: center;"> 4086 <a href="http://www.groupon.com/now"> 4087 <img width="550" height="466" data-original="docs/images/groupon.jpg" alt="Groupon Now!" class="example_retina" /> 4088 </a> 4089 </div> 4090 4091 <h2 id="examples-basecamp">Basecamp</h2> 4092 4093 <p> 4094 <a href="http://37signals.com/">37Signals</a> chose Backbone.js to create 4095 the <a href="http://basecamp.com/calendar">calendar feature</a> of its 4096 popular project management software <a href="http://basecamp.com/">Basecamp</a>. 4097 The Basecamp Calendar uses Backbone.js models and views in conjunction with the 4098 <a href="https://github.com/sstephenson/eco">Eco</a> templating system to 4099 present a polished, highly interactive group scheduling interface. 4100 </p> 4101 4102 <div style="text-align: center;"> 4103 <a href="http://basecamp.com/calendar"> 4104 <img width="530" height="380" data-original="docs/images/basecamp-calendar.jpg" alt="Basecamp Calendar" class="example_retina" /> 4105 </a> 4106 </div> 4107 4108 <h2 id="examples-slavery-footprint">Slavery Footprint</h2> 4109 4110 <p> 4111 <a href="http://slaveryfootprint.org/survey">Slavery Footprint</a> 4112 allows consumers to visualize how their consumption habits are 4113 connected to modern-day slavery and provides them with an opportunity 4114 to have a deeper conversation with the companies that manufacture the 4115 goods they purchased. 4116 Based in Oakland, California, the Slavery Footprint team works to engage 4117 individuals, groups, and businesses to build awareness for and create 4118 deployable action against forced labor, human trafficking, and modern-day 4119 slavery through online tools, as well as off-line community education and 4120 mobilization programs. 4121 </p> 4122 4123 <div style="text-align: center;"> 4124 <a href="http://slaveryfootprint.org/survey"> 4125 <img width="550" height="394" data-original="docs/images/slavery-footprint.jpg" alt="Slavery Footprint" class="example_retina" /> 4126 </a> 4127 </div> 4128 4129 <h2 id="examples-stripe">Stripe</h2> 4130 4131 <p> 4132 <a href="https://stripe.com">Stripe</a> provides an API for accepting 4133 credit cards on the web. Stripe's 4134 <a href="https://manage.stripe.com">management interface</a> was recently 4135 rewritten from scratch in CoffeeScript using Backbone.js as the primary 4136 framework, <a href="https://github.com/sstephenson/eco">Eco</a> for templates, <a href="http://sass-lang.com/">Sass</a> for stylesheets, and <a href="https://github.com/sstephenson/stitch">Stitch</a> to package 4137 everything together as <a href="http://commonjs.org/">CommonJS</a> modules. The new app uses 4138 <a href="https://stripe.com/docs/api">Stripe's API</a> directly for the 4139 majority of its actions; Backbone.js models made it simple to map 4140 client-side models to their corresponding RESTful resources. 4141 </p> 4142 4143 <div style="text-align: center;"> 4144 <a href="https://stripe.com"> 4145 <img width="555" height="372" data-original="docs/images/stripe.png" alt="Stripe" class="example_retina" /> 4146 </a> 4147 </div> 4148 4149 <h2 id="examples-airbnb">Airbnb</h2> 4150 4151 <p> 4152 <a href="http://airbnb.com">Airbnb</a> uses Backbone in many of its products. 4153 It started with <a href="http://m.airbnb.com">Airbnb Mobile Web</a> 4154 (built in six weeks by a team of three) and has since grown to 4155 <a href="https://www.airbnb.com/wishlists/popular">Wish Lists</a>, 4156 <a href="http://www.airbnb.com/match">Match</a>, 4157 <a href="http://www.airbnb.com/s/">Search</a>, Communities, Payments, and 4158 Internal Tools. 4159 </p> 4160 4161 <div style="text-align: center;"> 4162 <a href="http://m.airbnb.com/"> 4163 <img width="500" height="489" data-original="docs/images/airbnb.png" alt="Airbnb" class="example_image" /> 4164 </a> 4165 </div> 4166 4167 <h2 id="examples-soundcloud">SoundCloud Mobile</h2> 4168 4169 <p> 4170 <a href="http://soundcloud.com">SoundCloud</a> is the leading sound sharing 4171 platform on the internet, and Backbone.js provides the foundation for 4172 <a href="http://m.soundcloud.com">SoundCloud Mobile</a>. The project uses 4173 the public SoundCloud <a href="http://soundcloud.com/developers">API</a> 4174 as a data source (channeled through a nginx proxy), 4175 <a href="https://github.com/BorisMoore/jquery-tmpl">jQuery templates</a> 4176 for the rendering, <a href="http://docs.jquery.com/Qunit">Qunit 4177 </a> and <a href="http://www.phantomjs.org/">PhantomJS</a> for 4178 the testing suite. The JS code, templates and CSS are built for the 4179 production deployment with various Node.js tools like 4180 <a href="https://github.com/dsimard/ready.js">ready.js</a>, 4181 <a href="https://github.com/mde/jake">Jake</a>, 4182 <a href="https://github.com/tmpvar/jsdom">jsdom</a>. 4183 The <b>Backbone.History</b> was modified to support the HTML5 <tt>history.pushState</tt>. 4184 <b>Backbone.sync</b> was extended with an additional SessionStorage based cache 4185 layer. 4186 </p> 4187 4188 <div style="text-align: center;"> 4189 <a href="http://m.soundcloud.com"> 4190 <img width="266" height="555" data-original="docs/images/soundcloud.png" alt="SoundCloud" class="example_image" /> 4191 </a> 4192 </div> 4193 4194 <h2 id="examples-artsy">Art.sy</h2> 4195 4196 <p> 4197 <a href="http://artsy.net">Art.sy</a> is a place to discover art you'll 4198 love. Art.sy is built on Rails, using 4199 <a href="https://github.com/intridea/grape">Grape</a> to serve a robust 4200 <a href="http://artsy.net/api">JSON API</a>. The main site is a single page 4201 app written in CoffeeScript and uses Backbone to provide structure around 4202 this API. An admin panel and partner CMS have also been extracted into 4203 their own API-consuming Backbone projects. 4204 </p> 4205 4206 <div style="text-align: center;"> 4207 <a href="http://artsy.net"> 4208 <img width="550" height="550" data-original="docs/images/artsy.jpg" alt="Art.sy" class="example_retina" /> 4209 </a> 4210 </div> 4211 4212 <h2 id="examples-pandora">Pandora</h2> 4213 4214 <p> 4215 When <a href="http://www.pandora.com/newpandora">Pandora</a> redesigned 4216 their site in HTML5, they chose Backbone.js to help 4217 manage the user interface and interactions. For example, there's a model 4218 that represents the "currently playing track", and multiple views that 4219 automatically update when the current track changes. The station list is a 4220 collection, so that when stations are added or changed, the UI stays up to date. 4221 </p> 4222 4223 <div style="text-align: center;"> 4224 <a href="http://www.pandora.com/newpandora"> 4225 <img width="476" height="359" data-original="docs/images/pandora.jpg" alt="Pandora" class="example_retina" /> 4226 </a> 4227 </div> 4228 4229 <h2 id="examples-inkling">Inkling</h2> 4230 4231 <p> 4232 <a href="http://inkling.com/">Inkling</a> is a cross-platform way to 4233 publish interactive learning content. 4234 <a href="https://www.inkling.com/read/">Inkling for Web</a> uses Backbone.js 4235 to make hundreds of complex books — from student textbooks to travel guides and 4236 programming manuals — engaging and accessible on the web. Inkling supports 4237 WebGL-enabled 3D graphics, interactive assessments, social sharing, 4238 and a system for running practice code right 4239 in the book, all within a single page Backbone-driven app. Early on, the 4240 team decided to keep the site lightweight by using only Backbone.js and 4241 raw JavaScript. The result? Complete source code weighing in at a mere 4242 350kb with feature-parity across the iPad, iPhone and web clients. 4243 Give it a try with 4244 <a href="https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-4/function-definition-expressions">this excerpt from JavaScript: The Definitive Guide</a>. 4245 </p> 4246 4247 <div style="text-align: center;"> 4248 <a href="http://inkling.com"> 4249 <img width="550" height="361" data-original="docs/images/inkling.jpg" alt="Inkling" class="example_retina" /> 4250 </a> 4251 </div> 4252 4253 <h2 id="examples-code-school">Code School</h2> 4254 4255 <p> 4256 <a href="http://www.codeschool.com">Code School</a> courses teach people 4257 about various programming topics like <a href="http://coffeescript.org">CoffeeScript</a>, CSS, Ruby on Rails, 4258 and more. The new Code School course 4259 <a href="http://coffeescript.codeschool.com/levels/1/challenges/1">challenge page</a> 4260 is built from the ground up on Backbone.js, using 4261 everything it has to offer: the router, collections, models, and complex 4262 event handling. Before, the page was a mess of <a href="http://jquery.com/">jQuery</a> DOM manipulation 4263 and manual Ajax calls. Backbone.js helped introduce a new way to 4264 think about developing an organized front-end application in JavaScript. 4265 </p> 4266 4267 <div style="text-align: center;"> 4268 <a href="http://www.codeschool.com"> 4269 <img width="550" height="482" data-original="docs/images/code-school.jpg" alt="Code School" class="example_retina" /> 4270 </a> 4271 </div> 4272 4273 <h2 id="examples-cloudapp">CloudApp</h2> 4274 4275 <p> 4276 <a href="http://getcloudapp.com">CloudApp</a> is simple file and link 4277 sharing for the Mac. Backbone.js powers the web tools 4278 which consume the <a href="http://developer.getcloudapp.com">documented API</a> 4279 to manage Drops. Data is either pulled manually or pushed by 4280 <a href="http://pusher.com">Pusher</a> and fed to 4281 <a href="http://github.com/janl/mustache.js">Mustache</a> templates for 4282 rendering. Check out the <a href="http://cloudapp.github.com/engine">annotated source code</a> 4283 to see the magic. 4284 </p> 4285 4286 <div style="text-align: center;"> 4287 <a href="http://getcloudapp.com"> 4288 <img width="550" height="426" data-original="docs/images/cloudapp.jpg" alt="CloudApp" class="example_retina" /> 4289 </a> 4290 </div> 4291 4292 <h2 id="examples-seatgeek">SeatGeek</h2> 4293 4294 <p> 4295 <a href="http://seatgeek.com">SeatGeek</a>'s stadium ticket maps were originally 4296 developed with <a href="http://prototypejs.org/">Prototype.js</a>. Moving to Backbone.js and <a href="http://jquery.com/">jQuery</a> helped organize 4297 a lot of the UI code, and the increased structure has made adding features 4298 a lot easier. SeatGeek is also in the process of building a mobile 4299 interface that will be Backbone.js from top to bottom. 4300 </p> 4301 4302 <div style="text-align: center;"> 4303 <a href="http://seatgeek.com"> 4304 <img width="550" height="455" data-original="docs/images/seatgeek.jpg" alt="SeatGeek" class="example_retina" /> 4305 </a> 4306 </div> 4307 4308 <h2 id="examples-easel">Easel</h2> 4309 4310 <p> 4311 <a href="http://easel.io">Easel</a> is an in-browser, high fidelity web 4312 design tool that integrates with your design and development 4313 process. The Easel team uses CoffeeScript, Underscore.js and Backbone.js for 4314 their <a href="http://easel.io/demo">rich visual editor</a> as well as other 4315 management functions throughout the site. The structure of Backbone allowed 4316 the team to break the complex problem of building a visual editor into 4317 manageable components and still move quickly. 4318 </p> 4319 4320 <div style="text-align: center;"> 4321 <a href="http://easel.io"> 4322 <img width="550" height="395" data-original="docs/images/easel.jpg" alt="Easel" class="example_retina" /> 4323 </a> 4324 </div> 4325 4326 <h2 id="examples-jolicloud">Jolicloud</h2> 4327 4328 <p> 4329 <a href="http://www.jolicloud.com/">Jolicloud</a> is an open and independent 4330 platform and <a href="http://www.jolicloud.com/jolios">operating system</a> 4331 that provides music playback, video streaming, photo browsing and 4332 document editing — transforming low cost computers into beautiful cloud devices. 4333 The <a href="https://my.jolicloud.com/">new Jolicloud HTML5 app</a> was built 4334 from the ground up using Backbone and talks to the 4335 <a href="http://developers.jolicloud.com">Jolicloud Platform</a>, which is 4336 based on Node.js. Jolicloud works offline using the HTML5 AppCache, extends 4337 Backbone.sync to store data in IndexedDB or localStorage, and communicates 4338 with the <a href="http://www.jolicloud.com/jolios">Joli OS</a> via WebSockets. 4339 </p> 4340 4341 <div style="text-align: center;"> 4342 <a href="http://jolicloud.com/"> 4343 <img width="510" height="384" data-original="docs/images/jolicloud.jpg" alt="Jolicloud" class="example_retina" /> 4344 </a> 4345 </div> 4346 4347 <h2 id="examples-salon">Salon.io</h2> 4348 4349 <p> 4350 <a href="http://salon.io">Salon.io</a> provides a space where photographers, 4351 artists and designers freely arrange their visual art on virtual walls. 4352 <a href="http://salon.io">Salon.io</a> runs on <a href="http://rubyonrails.org/">Rails</a>, but does not use 4353 much of the traditional stack, as the entire frontend is designed as a 4354 single page web app, using Backbone.js, <a href="http://brunch.io/">Brunch</a> and 4355 <a href="http://coffeescript.org">CoffeeScript</a>. 4356 </p> 4357 4358 <div style="text-align: center;"> 4359 <a href="http://salon.io"> 4360 <img width="550" height="483" data-original="docs/images/salon.jpg" alt="Salon.io" class="example_retina" /> 4361 </a> 4362 </div> 4363 4364 <h2 id="examples-tilemill">TileMill</h2> 4365 4366 <p> 4367 Our fellow 4368 <a href="http://www.newschallenge.org/">Knight Foundation News Challenge</a> 4369 winners, <a href="http://mapbox.com/">MapBox</a>, created an open-source 4370 map design studio with Backbone.js: 4371 <a href="https://www.mapbox.com/tilemill/">TileMill</a>. 4372 TileMill lets you manage map layers based on shapefiles and rasters, and 4373 edit their appearance directly in the browser with the 4374 <a href="https://github.com/mapbox/carto">Carto styling language</a>. 4375 Note that the gorgeous <a href="http://mapbox.com/">MapBox</a> homepage 4376 is also a Backbone.js app. 4377 </p> 4378 4379 <div style="text-align: center;"> 4380 <a href="https://www.mapbox.com/tilemill/"> 4381 <img width="544" height="375" data-original="docs/images/tilemill.jpg" alt="TileMill" class="example_retina" /> 4382 </a> 4383 </div> 4384 4385 <h2 id="examples-blossom">Blossom</h2> 4386 4387 <p> 4388 <a href="http://blossom.io">Blossom</a> is a lightweight project management 4389 tool for lean teams. Backbone.js is heavily used in combination with 4390 <a href="http://coffeescript.org">CoffeeScript</a> to provide a smooth 4391 interaction experience. The app is packaged with <a href="http://brunch.io">Brunch</a>. 4392 The RESTful backend is built with <a href="http://flask.pocoo.org/">Flask</a> on Google App Engine. 4393 </p> 4394 4395 <div style="text-align: center;"> 4396 <a href="http://blossom.io"> 4397 <img width="550" height="367" data-original="docs/images/blossom.jpg" alt="Blossom" class="example_retina" /> 4398 </a> 4399 </div> 4400 4401 <h2 id="examples-trello">Trello</h2> 4402 4403 <p> 4404 <a href="http://trello.com">Trello</a> is a collaboration tool that 4405 organizes your projects into boards. A Trello board holds many lists of 4406 cards, which can contain checklists, files and conversations, and may be 4407 voted on and organized with labels. Updates on the board happen in 4408 real time. The site was built ground up using Backbone.js for all the 4409 models, views, and routes. 4410 </p> 4411 4412 <div style="text-align: center;"> 4413 <a href="http://trello.com"> 4414 <img width="550" height="416" data-original="docs/images/trello.jpg" alt="Trello" class="example_retina" /> 4415 </a> 4416 </div> 4417 4418 <h2 id="examples-tzigla">Tzigla</h2> 4419 4420 <p> 4421 <a href="http://twitter.com/evilchelu">Cristi Balan</a> and 4422 <a href="http://dira.ro">Irina Dumitrascu</a> created 4423 <a href="http://tzigla.com">Tzigla</a>, a collaborative drawing 4424 application where artists make tiles that connect to each other to 4425 create <a href="http://tzigla.com/boards/1">surreal drawings</a>. 4426 Backbone models help organize the code, routers provide 4427 <a href="http://tzigla.com/boards/1#!/tiles/2-2">bookmarkable deep links</a>, 4428 and the views are rendered with 4429 <a href="https://github.com/creationix/haml-js">haml.js</a> and 4430 <a href="http://zeptojs.com/">Zepto</a>. 4431 Tzigla is written in Ruby (<a href="http://rubyonrails.org/">Rails</a>) on the backend, and 4432 <a href="http://coffeescript.org">CoffeeScript</a> on the frontend, with 4433 <a href="http://documentcloud.github.com/jammit/">Jammit</a> 4434 prepackaging the static assets. 4435 </p> 4436 4437 <div style="text-align: center;"> 4438 <a href="http://www.tzigla.com/"> 4439 <img width="550" height="376" data-original="docs/images/tzigla.jpg" alt="Tzigla" class="example_retina" /> 4440 </a> 4441 </div> 4442 4443 <h2 id="changelog">Change Log</h2> 4444 4445 <b class="header">1.4.0</b> — <small><i>Feb. 19, 2019</i></small> 4446 — <a href="https://github.com/jashkenas/backbone/compare/1.3.3...1.4.0">Diff</a> 4447 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.4.0/index.html">Docs</a> 4448 <br /> 4449 <ul style="margin-top: 5px;"> 4450 <li> 4451 Collections now support the <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols">Javascript Iterator Protocol!</a> 4452 </li> 4453 <li> 4454 <tt>listenTo</tt> uses the listened object's public <tt>on</tt> method. 4455 This helps maintain interoperability between Backbone and other event 4456 libraries (including Node.js). 4457 </li> 4458 <li> 4459 Added support for setting instance properties before the constructor in 4460 <tt>ES2015 classes</tt> with a <tt>preinitialize</tt> method. 4461 </li> 4462 <li> 4463 <tt>Collection.get</tt> now checks if obj is a <tt>Model</tt> to allow 4464 retrieving models with an `attributes` key. 4465 </li> 4466 <li> 4467 Fixed several issues with Router's URL hashing and parsing. 4468 </li> 4469 </ul> 4470 4471 <b class="header">1.3.3</b> — <small><i>Apr. 5, 2016</i></small> 4472 — <a href="https://github.com/jashkenas/backbone/compare/1.2.3...1.3.3">Diff</a> 4473 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.3.3/index.html">Docs</a> 4474 <br /> 4475 <ul style="margin-top: 5px;"> 4476 <li> 4477 Added <tt>findIndex</tt> and <tt>findLastIndex</tt> Underscore methods to 4478 <tt>Collection</tt>. 4479 </li> 4480 <li> 4481 Added <tt>options.changes</tt> to <tt>Collection</tt> "update" event which 4482 includes added, merged, and removed models. 4483 </li> 4484 <li> 4485 Added support for <tt>Collection#mixin</tt> and <tt>Model#mixin</tt>. 4486 </li> 4487 <li> 4488 Ensured <tt>Collection#reduce</tt> and <tt>Collection#reduceRight</tt> 4489 work without an initial <tt>accumulator</tt> value. 4490 </li> 4491 <li> 4492 Ensured <tt>Collection#_removeModels</tt> always returns an array. 4493 </li> 4494 <li> 4495 Fixed a bug where <tt>Events.once</tt> with object syntax failed to bind 4496 context. 4497 </li> 4498 <li> 4499 Fixed <tt>Collection#_onModelEvent</tt> regression where triggering a 4500 <tt>change</tt> event without a <tt>model</tt> would error. 4501 </li> 4502 <li> 4503 Fixed <tt>Collection#set</tt> regression when <tt>parse</tt> returns a 4504 falsy value. 4505 </li> 4506 <li> 4507 Fixed <tt>Model#id</tt> regression where <tt>id</tt> would be 4508 unintentionally <tt>undefined</tt>. 4509 </li> 4510 <li> 4511 Fixed <tt>_removeModels</tt> regression which could cause an infinite loop 4512 under certain conditions. 4513 </li> 4514 <li> 4515 Removed <tt>component</tt> package support. 4516 </li> 4517 <li> 4518 Note that 1.3.3 fixes several bugs in versions 1.3.0 to 1.3.2. Please upgrade 4519 immediately if you are on one of those versions. 4520 </li> 4521 </ul> 4522 4523 <b class="header">1.2.3</b> — <small><i>Sept. 3, 2015</i></small> 4524 — <a href="https://github.com/jashkenas/backbone/compare/1.2.2...1.2.3">Diff</a> 4525 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.2.3/index.html">Docs</a> 4526 <br /> 4527 <ul style="margin-top: 5px;"> 4528 <li> 4529 Fixed a minor regression in 1.2.2 that would cause an error when adding 4530 a model to a collection <tt>at</tt> an out of bounds index. 4531 </li> 4532 </ul> 4533 4534 <b class="header">1.2.2</b> — <small><i>Aug. 19, 2015</i></small> 4535 — <a href="https://github.com/jashkenas/backbone/compare/1.2.1...1.2.2">Diff</a> 4536 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.2.2/index.html">Docs</a> 4537 <br /> 4538 <ul style="margin-top: 5px;"> 4539 <li> 4540 Collection methods <tt>find</tt>, <tt>filter</tt>, <tt>reject</tt>, <tt>every</tt>, 4541 <tt>some</tt>, and <tt>partition</tt> can now take a model-attributes-style predicate: 4542 <tt>this.collection.reject({user: 'guybrush'})</tt>. 4543 </li> 4544 <li> 4545 Backbone Events once again supports multiple-event maps 4546 (<tt>obj.on({'error change': action})</tt>). This was a previously 4547 undocumented feature inadvertently removed in 1.2.0. 4548 </li> 4549 <li> 4550 Added <tt>Collection#includes</tt> as an alias of <tt>Collection#contains</tt> 4551 and as a replacement for <tt>Collection#include</tt> in Underscore.js >= 1.8. 4552 </li> 4553 </ul> 4554 4555 <b class="header">1.2.1</b> — <small><i>Jun. 4, 2015</i></small> 4556 — <a href="https://github.com/jashkenas/backbone/compare/1.2.0...1.2.1">Diff</a> 4557 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.2.1/index.html">Docs</a> 4558 <br /> 4559 <ul style="margin-top: 5px;"> 4560 <li> 4561 <tt>Collection#add</tt> now avoids trying to parse a model instance when passed <tt>parse: false</tt>. 4562 </li> 4563 <li> 4564 Bug fix in <tt>Collection#remove</tt>. The removed models are now actually returned. 4565 </li> 4566 <li> 4567 <tt>Model#fetch</tt> no longer parses the response when passing <tt>parse: false</tt>. 4568 </li> 4569 <li> 4570 Bug fix for iframe-based History when used with JSDOM. 4571 </li> 4572 <li> 4573 Bug fix where <tt>Collection#invoke</tt> was not taking additional arguments. 4574 </li> 4575 <li> 4576 When using <tt>on</tt> with an event map, you can now pass the context as the 4577 second argument. This was a previously undocumented feature inadvertently 4578 removed in 1.2.0. 4579 </li> 4580 </ul> 4581 4582 <b class="header">1.2.0</b> — <small><i>May 13, 2015</i></small> 4583 — <a href="https://github.com/jashkenas/backbone/compare/1.1.2...1.2.0">Diff</a> 4584 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.2.0/index.html">Docs</a> 4585 <br /> 4586 <ul style="margin-top: 5px;"> 4587 <li> 4588 Added new hooks to Views to allow them to work without jQuery. See the 4589 <a href="https://github.com/jashkenas/backbone/wiki/Using-Backbone-without-jQuery">wiki page</a> 4590 for more info. 4591 </li> 4592 <li> 4593 As a neat side effect, Backbone.History no longer uses jQuery's 4594 event methods for <tt>pushState</tt> and <tt>hashChange</tt> listeners. 4595 We're native all the way. 4596 </li> 4597 <li> 4598 Also on the subject of jQuery, if you're using Backbone with CommonJS (node, browserify, webpack) 4599 Backbone will automatically try to load jQuery for you. 4600 </li> 4601 <li> 4602 Views now always delegate their events in <a href="#View-setElement">setElement</a>. 4603 You can no longer modify the events hash or your view's <tt>el</tt> property in 4604 <tt>initialize</tt>. 4605 </li> 4606 <li> 4607 Added an <tt>"update"</tt> event that triggers after any amount of 4608 models are added or removed from a collection. Handy to re-render lists 4609 of things without debouncing. 4610 </li> 4611 <li> 4612 <tt>Collection#at</tt> can take a negative index. 4613 </li> 4614 <li> 4615 Added <tt>modelId</tt> to Collection for generating unique ids on 4616 polymorphic collections. Handy for cases when your model ids would 4617 otherwise collide. 4618 </li> 4619 <li> 4620 Added an overridable <tt>_isModel</tt> for more advanced 4621 control of what's considered a model by your Collection. 4622 </li> 4623 <li> 4624 The <tt>success</tt> callback passed to <tt>Model#destroy</tt> is always 4625 called asynchronously now. 4626 </li> 4627 <li> 4628 <tt>Router#execute</tt> passes back the route name as its third argument. 4629 </li> 4630 <li> 4631 Cancel the current Router transition by returning <tt>false</tt> in 4632 <tt>Router#execute</tt>. Great for checking logged-in status or other 4633 prerequisites. 4634 </li> 4635 <li> 4636 Added <tt>getSearch</tt> and <tt>getPath</tt> methods to Backbone.History as 4637 cross-browser and overridable ways of slicing up the URL. 4638 </li> 4639 <li> 4640 Added <tt>delegate</tt> and <tt>undelegate</tt> as finer-grained versions 4641 of <tt>delegateEvents</tt> and <tt>undelegateEvents</tt>. Useful for plugin 4642 authors to use a consistent events interface in Backbone. 4643 </li> 4644 <li> 4645 A collection will only fire a "sort" event if its order was actually 4646 updated, not on every <tt>set</tt>. 4647 </li> 4648 <li> 4649 Any passed <tt>options.attrs</tt> are now respected when saving a model with 4650 <tt>patch: true</tt>. 4651 </li> 4652 <li> 4653 <tt>Collection#clone</tt> now sets the <tt>model</tt> and <tt>comparator</tt> 4654 functions of the cloned collection to the new one. 4655 </li> 4656 <li> 4657 Adding models to your Collection when specifying an <tt>at</tt> position 4658 now sends the actual position of your model in the <tt>add</tt> 4659 event, not just the one you've passed in. 4660 </li> 4661 <li> 4662 <tt>Collection#remove</tt> will now only return a list of models that 4663 have actually been removed from the collection. 4664 </li> 4665 <li> 4666 Fixed loading Backbone.js in strict ES2015 module loaders. 4667 </li> 4668 </ul> 4669 4670 <b class="header">1.1.2</b> — <small><i>Feb. 20, 2014</i></small> 4671 — <a href="https://github.com/jashkenas/backbone/compare/1.1.1...1.1.2">Diff</a> 4672 — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.1.2/index.html">Docs</a> 4673 <br /> 4674 <ul style="margin-top: 5px;"> 4675 <li> 4676 Backbone no longer tries to require jQuery in Node/CommonJS environments, 4677 for better compatibility with folks using Browserify. 4678 If you'd like to have Backbone use jQuery from Node, assign it like so: 4679 <tt>Backbone.$ = require('jquery');</tt> 4680 </li> 4681 <li> 4682 Bugfix for route parameters with newlines in them. 4683 </li> 4684 </ul> 4685 4686 <b class="header">1.1.1</b> — <small><i>Feb. 13, 2014</i></small> — <a href="https://github.com/jashkenas/backbone/compare/1.1.0...1.1.1">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.1.1/index.html">Docs</a><br /> 4687 <ul style="margin-top: 5px;"> 4688 <li> 4689 Backbone now registers itself for AMD (Require.js), Bower and Component, 4690 as well as being a CommonJS module and a regular (Java)Script. Whew. 4691 </li> 4692 <li> 4693 Added an <tt>execute</tt> hook to the Router, which allows you to hook 4694 in and custom-parse route arguments, like query strings, for example. 4695 </li> 4696 <li> 4697 Performance fine-tuning for Backbone Events. 4698 </li> 4699 <li> 4700 Better matching for Unicode in routes, in old browsers. 4701 </li> 4702 <li> 4703 Backbone Routers now handle query params in route fragments, passing 4704 them into the handler as the last argument. Routes specified as 4705 strings should no longer include the query string 4706 (<tt>'foo?:query'</tt> should be <tt>'foo'</tt>). 4707 </li> 4708 </ul> 4709 4710 <b class="header">1.1.0</b> — <small><i>Oct. 10, 2013</i></small> — <a href="https://github.com/jashkenas/backbone/compare/1.0.0...1.1.0">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.1.0/index.html">Docs</a><br /> 4711 <ul style="margin-top: 5px;"> 4712 <li> 4713 Made the return values of Collection's <tt>set</tt>, <tt>add</tt>, 4714 <tt>remove</tt>, and <tt>reset</tt> more useful. Instead of returning 4715 <tt>this</tt>, they now return the changed (added, removed or updated) 4716 model or list of models. 4717 </li> 4718 <li> 4719 Backbone Views no longer automatically attach options passed to the constructor as 4720 <tt>this.options</tt> and Backbone Models no longer attach <tt>url</tt> and 4721 <tt>urlRoot</tt> options, but you can do it yourself if you prefer. 4722 </li> 4723 <li> 4724 All <tt>"invalid"</tt> events now pass consistent arguments. First the 4725 model in question, then the error object, then options. 4726 </li> 4727 <li> 4728 You are no longer permitted to change the <b>id</b> of your model during 4729 <tt>parse</tt>. Use <tt>idAttribute</tt> instead. 4730 </li> 4731 <li> 4732 On the other hand, <tt>parse</tt> is now an excellent place to extract 4733 and vivify incoming nested JSON into associated submodels. 4734 </li> 4735 <li> 4736 Many tweaks, optimizations and bugfixes relating to Backbone 1.0, 4737 including URL overrides, mutation of options, bulk ordering, trailing 4738 slashes, edge-case listener leaks, nested model parsing... 4739 </li> 4740 </ul> 4741 4742 <b class="header">1.0.0</b> — <small><i>March 20, 2013</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.9.10...1.0.0">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/1.0.0/index.html">Docs</a><br /> 4743 <ul style="margin-top: 5px;"> 4744 <li> 4745 Renamed Collection's "update" to <a href="#Collection-set">set</a>, for 4746 parallelism with the similar <tt>model.set()</tt>, and contrast with 4747 <a href="#Collection-reset">reset</a>. It's now the default 4748 updating mechanism after a <a href="#Collection-fetch">fetch</a>. If you'd 4749 like to continue using "reset", pass <tt>{reset: true}</tt>. 4750 </li> 4751 <li> 4752 Your route handlers will now receive their URL parameters pre-decoded. 4753 </li> 4754 <li> 4755 Added <a href="#Events-listenToOnce">listenToOnce</a> as the analogue of 4756 <a href="#Events-once">once</a>. 4757 </li> 4758 <li> 4759 Added the <a href="#Collection-findWhere">findWhere</a> method to Collections, 4760 similar to <a href="#Collection-where">where</a>. 4761 </li> 4762 <li> 4763 Added the <tt>keys</tt>, <tt>values</tt>, <tt>pairs</tt>, <tt>invert</tt>, 4764 <tt>pick</tt>, and <tt>omit</tt> Underscore.js methods to Backbone Models. 4765 </li> 4766 <li> 4767 The routes in a Router's route map may now be function literals, 4768 instead of references to methods, if you like. 4769 </li> 4770 <li> 4771 <tt>url</tt> and <tt>urlRoot</tt> properties may now be passed as options 4772 when instantiating a new Model. 4773 </li> 4774 </ul> 4775 4776 <b class="header">0.9.10</b> — <small><i>Jan. 15, 2013</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.9.9...0.9.10">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.9.10/index.html">Docs</a><br /> 4777 <ul style="margin-top: 5px;"> 4778 <li> 4779 A <tt>"route"</tt> event is triggered on the router in addition 4780 to being fired on <tt>Backbone.history</tt>. 4781 </li> 4782 <li> 4783 Model validation is now only enforced by default in 4784 <tt>Model#save</tt> and no longer enforced by default upon 4785 construction or in <tt>Model#set</tt>, unless the <tt>{validate:true}</tt> 4786 option is passed. 4787 </li> 4788 <li> 4789 <tt>View#make</tt> has been removed. You'll need to use <tt>$</tt> directly to 4790 construct DOM elements now. 4791 </li> 4792 <li> 4793 Passing <tt>{silent:true}</tt> on change will no longer delay individual 4794 <tt>"change:attr"</tt> events, instead they are silenced entirely. 4795 </li> 4796 <li> 4797 The <tt>Model#change</tt> method has been removed, as delayed attribute 4798 changes are no longer available. 4799 </li> 4800 <li> 4801 Bug fix on <tt>change</tt> where attribute comparison uses <tt>!==</tt> 4802 instead of <tt>_.isEqual</tt>. 4803 </li> 4804 <li> 4805 Bug fix where an empty response from the server on save would not call 4806 the success function. 4807 </li> 4808 <li> 4809 <tt>parse</tt> now receives <tt>options</tt> as its second argument. 4810 </li> 4811 <li> 4812 Model validation now fires <tt>invalid</tt> event instead of 4813 <tt>error</tt>. 4814 </li> 4815 </ul> 4816 4817 <b class="header">0.9.9</b> — <small><i>Dec. 13, 2012</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.9.2...0.9.9">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.9.9/index.html">Docs</a><br /> 4818 <ul style="margin-top: 5px;"> 4819 <li> 4820 Added <a href="#Events-listenTo">listenTo</a> 4821 and <a href="#Events-stopListening">stopListening</a> to Events. They 4822 can be used as inversion-of-control flavors of <tt>on</tt> and <tt>off</tt>, 4823 for convenient unbinding of all events an object is currently listening to. 4824 <tt>view.remove()</tt> automatically calls <tt>view.stopListening()</tt>. 4825 </li> 4826 <li> 4827 When using <tt>add</tt> on a collection, passing <tt>{merge: true}</tt> 4828 will now cause duplicate models to have their attributes merged in to 4829 the existing models, instead of being ignored. 4830 </li> 4831 <li> 4832 Added <a href="#Collection-update">update</a> (which is also available as 4833 an option to <tt>fetch</tt>) for "smart" updating of sets of models. 4834 </li> 4835 <li> 4836 HTTP <tt>PATCH</tt> support in <a href="#Model-save">save</a> by passing 4837 <tt>{patch: true}</tt>. 4838 </li> 4839 <li> 4840 The <tt>Backbone</tt> object now extends <tt>Events</tt> so that you can 4841 use it as a global event bus, if you like. 4842 </li> 4843 <li> 4844 Added a <tt>"request"</tt> event to <a href="#Sync">Backbone.sync</a>, 4845 which triggers whenever a request begins to be made to the server. 4846 The natural complement to the <tt>"sync"</tt> event. 4847 </li> 4848 <li> 4849 Router URLs now support optional parts via parentheses, without having 4850 to use a regex. 4851 </li> 4852 <li> 4853 Backbone events now supports <tt>once</tt>, similar to Node's <tt>once</tt>, 4854 or jQuery's <tt>one</tt>. 4855 </li> 4856 <li> 4857 Backbone events now support jQuery-style event maps <tt>obj.on({click: action})</tt>. 4858 </li> 4859 <li> 4860 While listening to a <tt>reset</tt> event, the list of previous models 4861 is now available in <tt>options.previousModels</tt>, for convenience. 4862 </li> 4863 <li> 4864 <a href="#Model-validate">Validation</a> now occurs even during "silent" 4865 changes. This change means that the <tt>isValid</tt> method has 4866 been removed. Failed validations also trigger an error, even if an error 4867 callback is specified in the options. 4868 </li> 4869 <li> 4870 Consolidated <tt>"sync"</tt> and <tt>"error"</tt> events within 4871 <a href="#Sync">Backbone.sync</a>. They are now triggered regardless 4872 of the existence of <tt>success</tt> or <tt>error</tt> callbacks. 4873 </li> 4874 <li> 4875 For mixed-mode APIs, <tt>Backbone.sync</tt> now accepts 4876 <tt>emulateHTTP</tt> and <tt>emulateJSON</tt> as inline options. 4877 </li> 4878 <li> 4879 Collections now also proxy Underscore method name aliases (collect, 4880 inject, foldl, foldr, head, tail, take, and so on...) 4881 </li> 4882 <li> 4883 Removed <tt>getByCid</tt> from Collections. <tt>collection.get</tt> now 4884 supports lookup by both <tt>id</tt> and <tt>cid</tt>. 4885 </li> 4886 <li> 4887 After fetching a model or a collection, <i>all</i> defined <tt>parse</tt> 4888 functions will now be run. So fetching a collection and getting back new 4889 models could cause both the collection to parse the list, and then each model 4890 to be parsed in turn, if you have both functions defined. 4891 </li> 4892 <li> 4893 Bugfix for normalizing leading and trailing slashes in the Router 4894 definitions. Their presence (or absence) should not affect behavior. 4895 </li> 4896 <li> 4897 When declaring a View, <tt>options</tt>, <tt>el</tt>, <tt>tagName</tt>, 4898 <tt>id</tt> and <tt>className</tt> may now be defined as functions, if 4899 you want their values to be determined at runtime. 4900 </li> 4901 <li> 4902 Added a <tt>Backbone.ajax</tt> hook for more convenient overriding of 4903 the default use of <tt>$.ajax</tt>. If AJAX is too passé, set it to your 4904 preferred method for server communication. 4905 </li> 4906 <li> 4907 <tt>Collection#sort</tt> now triggers a <tt>sort</tt> event, instead 4908 of a <tt>reset</tt> event. 4909 </li> 4910 <li> 4911 Calling <tt>destroy</tt> on a Model will now return <tt>false</tt> if 4912 the model <tt>isNew</tt>. 4913 </li> 4914 <li> 4915 To set what library Backbone uses for DOM manipulation and Ajax calls, 4916 use <tt>Backbone.$ = ...</tt> instead of <tt>setDomLibrary</tt>. 4917 </li> 4918 <li> 4919 Removed the <tt>Backbone.wrapError</tt> helper method. Overriding 4920 <tt>sync</tt> should work better for those particular use cases. 4921 </li> 4922 <li> 4923 To improve the performance of <tt>add</tt>, <tt>options.index</tt> 4924 will no longer be set in the <tt>add</tt> event callback. 4925 <tt>collection.indexOf(model)</tt> can be used to retrieve the index 4926 of a model as necessary. 4927 </li> 4928 <li> 4929 For semantic and cross browser reasons, routes will now ignore search 4930 parameters. Routes like <tt>search?query=…&page=3</tt> should become 4931 <tt>search/…/3</tt>. 4932 </li> 4933 <li> 4934 <tt>Model#set</tt> no longer accepts another model as an argument. This leads 4935 to subtle problems and is easily replaced with <tt>model.set(other.attributes)</tt>. 4936 </li> 4937 </ul> 4938 4939 <b class="header">0.9.2</b> — <small><i>March 21, 2012</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.9.1...0.9.2">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.9.2/index.html">Docs</a><br /> 4940 <ul style="margin-top: 5px;"> 4941 <li> 4942 Instead of throwing an error when adding duplicate models to a collection, 4943 Backbone will now silently skip them instead. 4944 </li> 4945 <li> 4946 Added <a href="#Collection-push">push</a>, 4947 <a href="#Collection-pop">pop</a>, 4948 <a href="#Collection-unshift">unshift</a>, and 4949 <a href="#Collection-shift">shift</a> to collections. 4950 </li> 4951 <li> 4952 A model's <a href="#Model-changed">changed</a> hash is now exposed for 4953 easy reading of the changed attribute delta, since the model's last 4954 <tt>"change"</tt> event. 4955 </li> 4956 <li> 4957 Added <a href="#Collection-where">where</a> to collections for simple 4958 filtering. 4959 </li> 4960 <li> 4961 You can now use a single <a href="#Events-off">off</a> call 4962 to remove all callbacks bound to a specific object. 4963 </li> 4964 <li> 4965 Bug fixes for nested individual change events, some of which may be 4966 "silent". 4967 </li> 4968 <li> 4969 Bug fixes for URL encoding in <tt>location.hash</tt> fragments. 4970 </li> 4971 <li> 4972 Bug fix for client-side validation in advance of a <tt>save</tt> call 4973 with <tt>{wait: true}</tt>. 4974 </li> 4975 <li> 4976 Updated / refreshed the example 4977 <a href="examples/todos/index.html">Todo List</a> app. 4978 </li> 4979 </ul> 4980 4981 <b class="header">0.9.1</b> — <small><i>Feb. 2, 2012</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.9.0...0.9.1">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.9.1/index.html">Docs</a><br /> 4982 <ul style="margin-top: 5px;"> 4983 <li> 4984 Reverted to 0.5.3-esque behavior for validating models. Silent changes 4985 no longer trigger validation (making it easier to work with forms). 4986 Added an <tt>isValid</tt> function that you can use to check if a model 4987 is currently in a valid state. 4988 </li> 4989 <li> 4990 If you have multiple versions of jQuery on the page, you can now tell 4991 Backbone which one to use with <tt>Backbone.setDomLibrary</tt>. 4992 </li> 4993 <li> 4994 Fixes regressions in <b>0.9.0</b> for routing with "root", saving with 4995 both "wait" and "validate", and the order of nested "change" events. 4996 </li> 4997 </ul> 4998 4999 <b class="header">0.9.0</b> — <small><i>Jan. 30, 2012</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.5.3...0.9.0">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.9.0/index.html">Docs</a><br /> 5000 <ul style="margin-top: 5px;"> 5001 <li> 5002 Creating and destroying models with <tt>create</tt> and <tt>destroy</tt> 5003 are now optimistic by default. Pass <tt>{wait: true}</tt> as an option 5004 if you'd like them to wait for a successful server response to proceed. 5005 </li> 5006 <li> 5007 Two new properties on views: <tt>$el</tt> — a cached jQuery (or Zepto) 5008 reference to the view's element, and <tt>setElement</tt>, which should 5009 be used instead of manually setting a view's <tt>el</tt>. It will 5010 both set <tt>view.el</tt> and <tt>view.$el</tt> correctly, as well as 5011 re-delegating events on the new DOM element. 5012 </li> 5013 <li> 5014 You can now bind and trigger multiple spaced-delimited events at once. 5015 For example: <tt>model.on("change:name change:age", ...)</tt> 5016 </li> 5017 <li> 5018 When you don't know the key in advance, you may now call 5019 <tt>model.set(key, value)</tt> as well as <tt>save</tt>. 5020 </li> 5021 <li> 5022 Multiple models with the same <tt>id</tt> are no longer allowed in a 5023 single collection. 5024 </li> 5025 <li> 5026 Added a <tt>"sync"</tt> event, which triggers whenever a model's state 5027 has been successfully synced with the server (create, save, destroy). 5028 </li> 5029 <li> 5030 <tt>bind</tt> and <tt>unbind</tt> have been renamed to <tt>on</tt> 5031 and <tt>off</tt> for clarity, following jQuery's lead. 5032 The old names are also still supported. 5033 </li> 5034 <li> 5035 A Backbone collection's <tt>comparator</tt> function may now behave 5036 either like a <a href="http://underscorejs.org/#sortBy">sortBy</a> 5037 (pass a function that takes a single argument), 5038 or like a <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">sort</a> 5039 (pass a comparator function that expects two arguments). The comparator 5040 function is also now bound by default to the collection — so you 5041 can refer to <tt>this</tt> within it. 5042 </li> 5043 <li> 5044 A view's <tt>events</tt> hash may now also contain direct function 5045 values as well as the string names of existing view methods. 5046 </li> 5047 <li> 5048 Validation has gotten an overhaul — a model's <tt>validate</tt> function 5049 will now be run even for silent changes, and you can no longer create 5050 a model in an initially invalid state. 5051 </li> 5052 <li> 5053 Added <tt>shuffle</tt> and <tt>initial</tt> to collections, proxied 5054 from Underscore. 5055 </li> 5056 <li> 5057 <tt>Model#urlRoot</tt> may now be defined as a function as well as a 5058 value. 5059 </li> 5060 <li> 5061 <tt>View#attributes</tt> may now be defined as a function as well as a 5062 value. 5063 </li> 5064 <li> 5065 Calling <tt>fetch</tt> on a collection will now cause all fetched JSON 5066 to be run through the collection's model's <tt>parse</tt> function, if 5067 one is defined. 5068 </li> 5069 <li> 5070 You may now tell a router to <tt>navigate(fragment, {replace: true})</tt>, 5071 which will either use <tt>history.replaceState</tt> or 5072 <tt>location.hash.replace</tt>, in order to change the URL without adding 5073 a history entry. 5074 </li> 5075 <li> 5076 Within a collection's <tt>add</tt> and <tt>remove</tt> events, the index 5077 of the model being added or removed is now available as <tt>options.index</tt>. 5078 </li> 5079 <li> 5080 Added an <tt>undelegateEvents</tt> to views, allowing you to manually 5081 remove all configured event delegations. 5082 </li> 5083 <li> 5084 Although you shouldn't be writing your routes with them in any case — 5085 leading slashes (<tt>/</tt>) are now stripped from routes. 5086 </li> 5087 <li> 5088 Calling <tt>clone</tt> on a model now only passes the attributes 5089 for duplication, not a reference to the model itself. 5090 </li> 5091 <li> 5092 Calling <tt>clear</tt> on a model now removes the <tt>id</tt> attribute. 5093 </li> 5094 </ul> 5095 5096 <p> 5097 <b class="header">0.5.3</b> — <small><i>August 9, 2011</i></small> — <a href="https://github.com/jashkenas/backbone/compare/0.5.2...0.5.3">Diff</a> — <a href="https://cdn.rawgit.com/jashkenas/backbone/0.5.3/index.html">Docs</a><br /> 5098 A View's