Permalink
Browse files

Some content re-org in the index.

  • Loading branch information...
1 parent 953512d commit efa3e48814410efe240c014af987629a8f16dae4 @addyosmani committed Aug 26, 2012
Showing with 82 additions and 63 deletions.
  1. BIN backbone-fundamentals.epub
  2. +38 −33 backbone-fundamentals.rtf
  3. +23 −16 index.html
  4. +21 −14 index.md
View
Binary file not shown.
View
@@ -71,6 +71,7 @@ Routers
Namespacing
}}}
\sa180\par}
+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 Practical: Todos - Your First Application (coming soon)\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 {\field{\*\fldinst{HYPERLINK "#backboneboilerplate"}}{\fldrslt{\ul
Backbone Boilerplate & Grunt BBB
}}}
@@ -87,58 +88,59 @@ Common Problems & Solutions
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Cleanly Disposing Views\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Disposing Parent And Child Views\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Appending Views\sa180\par}
-{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 {\field{\*\fldinst{HYPERLINK "#restfulapps"}}{\fldrslt{\ul
-RESTful Applications
-}}}
-\par}
-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#restful"}}{\fldrslt{\ul
-Building RESTful applications with Backbone.js
-}}}
-\par}
-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#stack1"}}{\fldrslt{\ul
-Building Backbone.js apps with Node.js, Express, Mongoose and MongoDB
-}}}
-\par}
-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#stack2"}}{\fldrslt{\ul
-Building Backbone.js apps with Ruby, Sinatra, Haml and MongoDB
-}}}
-\par}
-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#pagination"}}{\fldrslt{\ul
-Paginating Backbone.js Requests & Collections
-}}}
- *\sa180\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 {\field{\*\fldinst{HYPERLINK "#advanced"}}{\fldrslt{\ul
-Going Modular
+Modular Development
}}}
\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#modularjs"}}{\fldrslt{\ul
-Modular JavaScript
+Introduction
}}}
\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#organizingmodules"}}{\fldrslt{\ul
Organizing modules with Require.js and AMD
}}}
\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#externaltemplates"}}{\fldrslt{\ul
-Keeping your templates external with the Require.js text plugin
+Keeping your templates external
+}}}
+\par}
+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#practicalrequirejs"}}{\fldrslt{\ul
+Practical: A Modular App Using AMD & Require.js
}}}
\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#optimizingrequirejs"}}{\fldrslt{\ul
-Optimizing Backbone apps for production with the Require.js Optimizer
+Optimize Apps With The Require.js Optimizer
}}}
\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#optimizebuild"}}{\fldrslt{\ul
-Optimize and Build a Backbone.js Application With Require.js Using Packages
+Optimize Apps With Require.js Using Packages
}}}
*\par}
-{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#practicalrequirejs"}}{\fldrslt{\ul
-Practical: A Modular Backbone.js Application Using AMD & Require.js
-}}}
-\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#decouplingbackbone"}}{\fldrslt{\ul
Decoupling Backbone With The Mediator and Facade patterns
}}}
+\sa180\par}
+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 {\field{\*\fldinst{HYPERLINK "#restfulapps"}}{\fldrslt{\ul
+RESTful Applications With Backbone.js
+}}}
+\par}
+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#restful"}}{\fldrslt{\ul
+Building RESTful applications
+}}}
+\par}
+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#stack1"}}{\fldrslt{\ul
+Apps With Node.js, Express, Mongoose and MongoDB
+}}}
+\par}
+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#stack2"}}{\fldrslt{\ul
+Apps with Ruby, Sinatra, Haml and MongoDB
+}}}
\par}
+{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab {\field{\*\fldinst{HYPERLINK "#pagination"}}{\fldrslt{\ul
+Paginating Backbone.js Requests & Collections
+}}}
+ *\sa180\par}
+{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 Mobile Applications\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Backbone & jQuery Mobile\par}
{\pard \ql \f0 \sa0 \li720 \fi-360 \endash \tx360\tab Practical: Building A Modular Mobile App With Backbone & jQuery Mobile\sa180\par}
{\pard \ql \f0 \sa180 \li360 \fi-360 \bullet \tx360\tab \b \fs24 {\field{\*\fldinst{HYPERLINK "#testing"}}{\fldrslt{\ul
@@ -501,7 +503,7 @@ this
{\pard \ql \f0 \sa0 \li360 \fi-360 \bullet \tx360\tab Clear and flexible conventions for structuring applications. Backbone doesn\u8217't force usage of all of its components and can work with only those needed.\sa180\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs32 ##The Internals\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 What is Backbone?\par}
-{\pard \ql \f0 \sa180 \li0 \fi0 Backbone.js is one of a number of JavaScript frameworks for creating MVC-like web applications. On the front-end, it\u8217's my architectural framework of choice as it\u8217's both mature, relatively lightweight and can be easily tested using third-party toolkits such as Jasmine or QUnit. Other MVC frameworks you may be familiar with include Ember.js (SproutCore 2.0), Spine, YUILibrary and JavaScriptMVC.\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 As a short reminder, Backbone.js is one of a number of JavaScript frameworks for creating MVC-like web applications. On the front-end, it\u8217's my architectural framework of choice as it\u8217's both mature, relatively lightweight and can be easily tested using third-party toolkits such as Jasmine or QUnit. Other MVC frameworks you may be familiar with include Ember.js (SproutCore 2.0), Spine, YUILibrary and JavaScriptMVC.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Backbone is maintained by a number of contributors, most notably: Jeremy Ashkenas, creator of CoffeeScript, Docco and Underscore.js. As Jeremy is a believer in detailed documentation, there\u8217's a level of comfort in knowing you\u8217're unlikely to run into issues which are either not explained in the official docs or which can\u8217't be nailed down with some assistance from the #documentcloud IRC channel. I strongly recommend using the latter if you find yourself getting stuck.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Why should you consider using it?\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Backbone\u8217's main benefits, regardless of your target platform or device, include helping:\par}
@@ -712,7 +714,7 @@ id: 'header', // optional\par}
{\pard \ql \f0 \sa180 \li0 \fi0 The {\f1 _.template} method in Underscore compiles JavaScript templates into functions which can be evaluated for rendering. In the above view, I\u8217'm passing the markup from a template with id {\f1 results-template} to {\f1 _.template()} to be compiled. Next, I set the html of the {\f1 el} DOM element to the output of processing a JSON version of the model associated with the view through the compiled template.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Presto! This populates the template, giving you a data-complete set of markup in just a few short lines of code.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 {\b The {\f1 events} attribute}\par}
-{\pard \ql \f0 \sa180 \li0 \fi0 The Backbone {\f1 events} attribute allows us to attach event listeners to either custom selectors, or directly to {\f1 el} if no selector is provided. An event takes the form {\f1 \{"eventName selector": "callbackFunction"\}} and a number of event-types are supported, including {\f1 click}, {\f1 submit}, {\f1 mouseover}, {\f1 dblclick} and more.\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 The Backbone {\f1 events} attribute allows us to attach event listeners to either custom selectors, or directly to {\f1 el} if no selector is provided. An event takes the form {\f1 \{"eventName selector": "callbackFunction"\}} and a number of DOM event-types are supported, including {\f1 click}, {\f1 submit}, {\f1 mouseover}, {\f1 dblclick} and more.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 What isn\u8217't instantly obvious is that under the bonnet, Backbone uses jQuery\u8217's {\f1 .delegate()} to provide instant support for event delegation but goes a little further, extending it so that {\f1 this} always refers to the current view object. The only thing to really keep in mind is that any string callback supplied to the events attribute must have a corresponding function with the same name within the scope of your view.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \b \fs28 Collections\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Collections are sets of Models and are created by extending {\f1 Backbone.Collection}.\par}
@@ -1687,16 +1689,19 @@ render : function () \{\line
\}\par}
{\pard \ql \f0 \sa180 \li0 \fi0 This works in that one doesn\u8217't need to worry about maintaining the order of your DOM elements when appending. Views are initialized early and the render() method doesn\u8217't need to take on too many responsibilities at once. Unfortunately, a downside is that you don\u8217't have the ability to set the {\f1 tagName} of elements and events need to be re-delegated.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 An alternative approach which doesn\u8217't suffer from the re-delegation problem could be written as follows:\par}
-{\pard \ql \f0 \sa180 \li0 \fi0 ```javascript initialize : function () \{\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 ```javascript\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 initialize : function () \{\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \},\par}
{\pard \ql \f0 \sa180 \li0 \fi0 render : function () \{\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 this.$el.empty();\line
\line
this.innerView1 = new Subview(\{options\});\line
this.innerView2 = new Subview(\{options\});\line
\line
+\line
this.$el.append(this.innerView1.render().el, this.innerView2.render().el);\par}
-{\pard \ql \f0 \sa180 \li0 \fi0 \} ``{\f1 In this version, we also don't require a template containing empty placeholders and the issue with}tagName`s is solved as they are defined by the view once again.\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 \}\par}
+{\pard \ql \f0 \sa180 \li0 \fi0 ``{\f1 In this version, we also don't require a template containing empty placeholders and the issue with}tagName`s is solved as they are defined by the view once again.\par}
{\pard \ql \f0 \sa180 \li0 \fi0 Yet another variation which moves logic into an {\f1 onRender} event, could be written with only a few subtle changes:\par}
{\pard \ql \f0 \sa180 \li0 \fi0 \f1 initialize : function () \{\line
this.on('render', this.onRender);\line
View
@@ -66,6 +66,7 @@ <h2 id="table-of-contents">Table Of Contents</h2>
<li><a href="#thebasics-routers">Routers</a></li>
<li><a href="#thebasics-namespacing">Namespacing</a></li>
</ul></li>
+<li><h4>Practical: Todos - Your First Application (coming soon)</h4></li>
<li><h4><a href="#backboneboilerplate">Backbone Boilerplate &amp; Grunt BBB</a> *</h4></li>
<li><h4><a href="#commonproblems">Common Problems &amp; Solutions</a> *</h4>
<ul>
@@ -78,22 +79,25 @@ <h2 id="table-of-contents">Table Of Contents</h2>
<li>Disposing Parent And Child Views</li>
<li>Appending Views</li>
</ul></li>
-<li><h4><a href="#restfulapps">RESTful Applications</a></h4>
+<li><h4><a href="#advanced">Modular Development</a></h4>
<ul>
-<li><a href="#restful">Building RESTful applications with Backbone.js</a></li>
-<li><a href="#stack1">Building Backbone.js apps with Node.js, Express, Mongoose and MongoDB</a></li>
-<li><a href="#stack2">Building Backbone.js apps with Ruby, Sinatra, Haml and MongoDB</a></li>
+<li><a href="#modularjs">Introduction</a></li>
+<li><a href="#organizingmodules">Organizing modules with Require.js and AMD</a></li>
+<li><a href="#externaltemplates">Keeping your templates external</a></li>
+<li><a href="#practicalrequirejs">Practical: A Modular App Using AMD &amp; Require.js</a></li>
+<li><a href="#optimizingrequirejs">Optimize Apps With The Require.js Optimizer</a></li>
+<li><a href="#optimizebuild">Optimize Apps With Require.js Using Packages</a> *</li>
+<li><a href="#decouplingbackbone">Decoupling Backbone With The Mediator and Facade patterns</a></li>
+</ul></li>
+<li><h4><a href="#restfulapps">RESTful Applications With Backbone.js</a></h4>
+<ul>
+<li><a href="#restful">Building RESTful applications</a></li>
+<li><a href="#stack1">Apps With Node.js, Express, Mongoose and MongoDB</a></li>
+<li><a href="#stack2">Apps with Ruby, Sinatra, Haml and MongoDB</a></li>
<li><a href="#pagination">Paginating Backbone.js Requests &amp; Collections</a> *</li>
</ul></li>
-<li><h4><a href="#advanced">Going Modular</a></h4>
+<li><h4>Mobile Applications</h4>
<ul>
-<li><a href="#modularjs">Modular JavaScript</a></li>
-<li><a href="#organizingmodules">Organizing modules with Require.js and AMD</a></li>
-<li><a href="#externaltemplates">Keeping your templates external with the Require.js text plugin</a></li>
-<li><a href="#optimizingrequirejs">Optimizing Backbone apps for production with the Require.js Optimizer</a></li>
-<li><a href="#optimizebuild">Optimize and Build a Backbone.js Application With Require.js Using Packages</a> *</li>
-<li><a href="#practicalrequirejs">Practical: A Modular Backbone.js Application Using AMD &amp; Require.js</a></li>
-<li><a href="#decouplingbackbone">Decoupling Backbone With The Mediator and Facade patterns</a></li>
<li>Backbone &amp; jQuery Mobile</li>
<li>Practical: Building A Modular Mobile App With Backbone &amp; jQuery Mobile</li>
</ul></li>
@@ -416,7 +420,7 @@ <h3 id="backbone.js">Backbone.js</h3>
</ul>
<h2 id="the-internals">##<a name="theinternals">The Internals</a></h2>
<h3 id="what-is-backbone">What is Backbone?</h3>
-<p>Backbone.js is one of a number of JavaScript frameworks for creating MVC-like web applications. On the front-end, it's my architectural framework of choice as it's both mature, relatively lightweight and can be easily tested using third-party toolkits such as Jasmine or QUnit. Other MVC frameworks you may be familiar with include Ember.js (SproutCore 2.0), Spine, YUILibrary and JavaScriptMVC.</p>
+<p>As a short reminder, Backbone.js is one of a number of JavaScript frameworks for creating MVC-like web applications. On the front-end, it's my architectural framework of choice as it's both mature, relatively lightweight and can be easily tested using third-party toolkits such as Jasmine or QUnit. Other MVC frameworks you may be familiar with include Ember.js (SproutCore 2.0), Spine, YUILibrary and JavaScriptMVC.</p>
<p>Backbone is maintained by a number of contributors, most notably: Jeremy Ashkenas, creator of CoffeeScript, Docco and Underscore.js. As Jeremy is a believer in detailed documentation, there's a level of comfort in knowing you're unlikely to run into issues which are either not explained in the official docs or which can't be nailed down with some assistance from the #documentcloud IRC channel. I strongly recommend using the latter if you find yourself getting stuck.</p>
<h3 id="why-should-you-consider-using-it">Why should you consider using it?</h3>
<p>Backbone's main benefits, regardless of your target platform or device, include helping:</p>
@@ -628,7 +632,7 @@ <h4 id="what-is-el">What is <code>el</code>?</h4>
<p>The <code>_.template</code> method in Underscore compiles JavaScript templates into functions which can be evaluated for rendering. In the above view, I'm passing the markup from a template with id <code>results-template</code> to <code>_.template()</code> to be compiled. Next, I set the html of the <code>el</code> DOM element to the output of processing a JSON version of the model associated with the view through the compiled template.</p>
<p>Presto! This populates the template, giving you a data-complete set of markup in just a few short lines of code.</p>
<p><strong>The <code>events</code> attribute</strong></p>
-<p>The Backbone <code>events</code> attribute allows us to attach event listeners to either custom selectors, or directly to <code>el</code> if no selector is provided. An event takes the form <code>{&quot;eventName selector&quot;: &quot;callbackFunction&quot;}</code> and a number of event-types are supported, including <code>click</code>, <code>submit</code>, <code>mouseover</code>, <code>dblclick</code> and more.</p>
+<p>The Backbone <code>events</code> attribute allows us to attach event listeners to either custom selectors, or directly to <code>el</code> if no selector is provided. An event takes the form <code>{&quot;eventName selector&quot;: &quot;callbackFunction&quot;}</code> and a number of DOM event-types are supported, including <code>click</code>, <code>submit</code>, <code>mouseover</code>, <code>dblclick</code> and more.</p>
<p>What isn't instantly obvious is that under the bonnet, Backbone uses jQuery's <code>.delegate()</code> to provide instant support for event delegation but goes a little further, extending it so that <code>this</code> always refers to the current view object. The only thing to really keep in mind is that any string callback supplied to the events attribute must have a corresponding function with the same name within the scope of your view.</p>
<h3 id="collections"><a name="thebasics-collections" id="thebasics-collections">Collections</a></h3>
<p>Collections are sets of Models and are created by extending <code>Backbone.Collection</code>.</p>
@@ -1547,16 +1551,19 @@ <h4 id="nesting-what-is-the-best-approach-for-rendering-and-appending-sub-views-
}</code></pre>
<p>This works in that one doesn't need to worry about maintaining the order of your DOM elements when appending. Views are initialized early and the render() method doesn't need to take on too many responsibilities at once. Unfortunately, a downside is that you don't have the ability to set the <code>tagName</code> of elements and events need to be re-delegated.</p>
<p>An alternative approach which doesn't suffer from the re-delegation problem could be written as follows:</p>
-<p>```javascript initialize : function () {</p>
+<p>```javascript</p>
+<p>initialize : function () {</p>
<p>},</p>
<p>render : function () {</p>
<pre><code>this.$el.empty();
this.innerView1 = new Subview({options});
this.innerView2 = new Subview({options});
+
this.$el.append(this.innerView1.render().el, this.innerView2.render().el);</code></pre>
-<p>} ``<code>In this version, we also don't require a template containing empty placeholders and the issue with</code>tagName`s is solved as they are defined by the view once again.</p>
+<p>}</p>
+<p>``<code>In this version, we also don't require a template containing empty placeholders and the issue with</code>tagName`s is solved as they are defined by the view once again.</p>
<p>Yet another variation which moves logic into an <code>onRender</code> event, could be written with only a few subtle changes:</p>
<pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="dt">initialize </span>: <span class="kw">function</span> () {
<span class="kw">this</span>.<span class="fu">on</span>(<span class="ch">&#39;render&#39;</span>, <span class="kw">this</span>.<span class="fu">onRender</span>);
Oops, something went wrong.

0 comments on commit efa3e48

Please sign in to comment.