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