<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>AaronHardy.com</title>
	<atom:link href="http://aaronhardy.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://aaronhardy.com</link>
	<description>For all your Aaron Hardy needs.</description>
	<lastBuildDate>Mon, 20 May 2013 15:35:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dependency Injection And IoC Containers</title>
		<link>http://aaronhardy.com/general-programming/dependency-injection-and-ioc-containers/</link>
		<comments>http://aaronhardy.com/general-programming/dependency-injection-and-ioc-containers/#comments</comments>
		<pubDate>Sat, 11 May 2013 06:11:03 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[General Programming]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[dependency injection]]></category>
		<category><![CDATA[injectorjs]]></category>
		<category><![CDATA[inversion of control]]></category>
		<category><![CDATA[software patterns]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1429</guid>
		<description><![CDATA[The dependency injection pattern is one of my all-time favorite patterns in software design. The concept, in its most simple form, is so simple yet so powerful. In essence, it takes us from this: var TweetStream = function&#40;&#41; &#123; this.twitter = new TwitterService&#40;&#41;; &#125;; &#160; TweetStream.prototype.streamTweets = function&#40;&#41; &#123; … var tweets = this.twitter.getTweets&#40;&#41;; … [...]]]></description>
				<content:encoded><![CDATA[<p>The <a href="http://en.wikipedia.org/wiki/Dependency_injection" target="_blank">dependency injection pattern</a> is one of my all-time favorite patterns in software design. The concept, in its most simple form, is so simple yet so powerful.</p>
<p>In essence, it takes us from this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> TweetStream <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">twitter</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TwitterService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
TweetStream.<span style="color: #000066; font-weight: bold;">prototype</span>.<span style="color: #660066;">streamTweets</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    …
    <span style="color: #000066; font-weight: bold;">var</span> tweets <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">twitter</span>.<span style="color: #660066;">getTweets</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    …
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> stream <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TweetStream<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
stream.<span style="color: #660066;">streamTweets</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>To this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> TweetStream <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>twitter<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">twitter</span> <span style="color: #339933;">=</span> twitter<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
TweetStream.<span style="color: #000066; font-weight: bold;">prototype</span>.<span style="color: #660066;">streamTweets</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    …
    <span style="color: #000066; font-weight: bold;">var</span> tweets <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">twitter</span>.<span style="color: #660066;">getTweets</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    …
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> twitter <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TwitterService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">var</span> stream <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TweetStream<span style="color: #009900;">&#40;</span>twitter<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
stream.<span style="color: #660066;">streamTweets</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>So what&#8217;s the big deal?</p>
<p>In the first example, TweetStream creates the TwitterService instance. TweetStream is forced to have a knowledge of (1) the exact &#8220;class&#8221; it should use to communicate with Twitter, (2) where and how to access the constructor, and (3) how to create an instance and appropriately initialize the object (passing parameters to the constructor, calling methods after the fact, etc.).  </p>
<p>In the second example, TweetStream does not need to know any of these things since TwitterService is created by a third party and later passed into TweetStream. TweetStream only needs to know how to interact with the instance it is passed.</p>
<p>Although seemingly benign, the additional knowledge that TweetStream is forced to have in the first example increases its <a href="http://www.xyzws.com/scjp/SGS11/5/2" target="_blank">coupling</a> to its dependencies while decreasing its own <a href="http://www.xyzws.com/scjp/SGS11/5/2" target="_blank">cohesion</a>. The additional coupling leads to code that can be difficult to test and less flexible at runtime. If we were to &#8220;inject&#8221; the dependencies rather than forcing TweetStream to create or find them, we can easily mock dependencies during unit tests and provide them directly to the subject being tested. At runtime, we can easily swap out the object being provided as a dependency based on rules or contexts.<span id="more-1429"></span></p>
<h3>Inversion Of Control Containers</h3>
<p>So what does this have to do with an IoC container? An inversion of control container, or IoC container for short, assists in dependency injection and essentially fills three roles. These roles are often split between a container and an injector, but for simplicity I&#8217;ll address them as though they are one in the same. Let&#8217;s have a look at each role.</p>
<p><b>Dependency Rule Registry</b></p>
<p>In our case study, TweetStream knows it needs a service to talk to Twitter. Depending on the dependency injection implementation, TweetStream can request this dependency in a variety of ways. In JavaScript, where <a href="http://en.wikipedia.org/wiki/Type_system#Static_typing" target="_blank">static typing</a>, <a href="http://www.codeproject.com/Articles/22769/Introduction-to-Object-Oriented-Programming-Concep#Interface" target="_blank">interfaces</a>, and <a href="http://en.wikipedia.org/wiki/Java_annotation" target="_blank">language-based annotations</a> don&#8217;t exist, the dependency would generally be requested by a name in the form of a string. For example, TweetStream may state that it needs &#8220;twitterService&#8221; or &#8220;twitter&#8221; or &#8220;TheTwits&#8221;&#8211;whatever name seems reasonable.  The important part is that some actor in the system needs to match up this name with a rule for how to create or retrieve the dependency.</p>
<p>That&#8217;s where the IoC container comes in. The IoC container might have rules like the following:</p>
<ul>
<li>When &#8220;twitter&#8221; is requested, provide a new instance using the TwitterService constructor.</li>
<li>When &#8220;chat&#8221; is requested, provide whatever is returned from ChatFactory.</li>
<li>When &#8220;logger&#8221; is requested, provide a singleton instance of AsyncLogger.</li>
<li>When &#8220;dialog&#8221; is requested, provide this specific object.
<li>When &#8220;rank&#8221; is requested, provide the value 1337.</li>
</ul>
<p><b>Injector</b></p>
<p>Now with our rules defined, we can use them to create or retrieve a dependency. Let&#8217;s say our object to receive dependencies&#8211;which we&#8217;ll call our injectee&#8211;is provided to the IoC container for dependency injection. Let&#8217;s say, for example, the injectee requests &#8220;chat&#8221; and &#8220;dialog&#8221; dependencies. The IoC container looks up the rule mapped to &#8220;chat&#8221;, runs ChatFactory which happens to instantiate a chat object and configures it so it&#8217;s all ready to go, then injects the chat object into the injectee.  The container then looks at the rule for &#8220;dialog&#8221;, and, by golly, when the rule was being configured on the IoC container, a specific object was provided to the IoC container that should always be used when the &#8220;dialog&#8221; dependency is requested. The IoC container then provides that specific object to the injectee.  If another injectee later asked for the &#8220;dialog&#8221; dependency, the same object would be provided to that injectee as well. As you can see, the rules offer quite a bit of flexibility.</p>
<p>In summary, the injector uses rules to create or retrieve dependencies and inject them into objects requesting them.</p>
<p><b>Dependency Object And Value Registry</b></p>
<p>In our first two rules, we use a constructor and a factory to create dependency objects at the moment they are called for:</p>
<ul>
<li>When &#8220;twitter&#8221; is requested, provide a new instance using the TwitterService constructor.</li>
<li>When &#8220;chat&#8221; is requested, provide whatever is returned from ChatFactory.</li>
</ul>
<p>On the other hand, some rules require that the IoC container hold onto dependency objects or values so they can be provided as dependencies to injectees at a later time rather than being re-created each time they are requested.  The last three rules I listed pertain here:</p>
<ul>
<li>When &#8220;logger&#8221; is requested, provide a singleton instance of AsyncLogger</li>
<li>When &#8220;dialog&#8221; is requested, provide this specific object.
<li>When &#8220;rank&#8221; is requested, provide the value 1337.</li>
</ul>
<p>In each of these, the container is holding onto objects or values so they can be provided as dependencies to injectees at a later time. In this manner, the IoC container becomes a registry of objects and values.</p>
<p>I&#8217;m kind of sneaking this in here, but in the case of the rule providing a singleton instance, you can avoid the woes of self-enforced singletons and reap the bounties of context-based singletons. Oh the wonders of IoC containers! Check out <a href="http://joelhooks.com/blog/2013/05/01/when-is-a-singleton-not-a-singleton/" target="_blank">this post by Joel Hooks</a> for more on this.</p>
<h3>Less Hand-waving, More Code</h3>
<p>To make a long story short, I&#8217;ve been playing around with dependency injection in JavaScript lately.  It&#8217;s still fairly new territory in this JavaScript world of ours though is becoming increasingly more popular thanks in large part to <a href="http://angularjs.org/" target="_blank">AngularJS</a> which provides dependency injection out of the box.  <a href="http://deftjs.org/" target="_blank">DeftJS</a> is also melding dependency injection into frameworks like <a href="http://www.sencha.com/products/extjs/" target="_blank">Ext JS</a> and <a href="http://www.sencha.com/products/touch/" target="_blank">Sencha Touch</a>.</p>
<p>In my frolicking about a year ago, I felt like cooking up an expressive, dependency-free, lightweight IoC container I called Injector.js which you can <a href="https://github.com/Aaronius/injectorjs" target="_blank">find on GitHub</a>.  Although the code may happen to prove useful for someone, I mention it here with the mere hope that the examples in the <a href="https://github.com/Aaronius/injectorjs/blob/master/README.md" target="_blank">readme</a> and the <a href="https://github.com/Aaronius/injectorjs/blob/master/spec/spec.js" target="_blank">unit tests</a> can help solidify some of the concepts I&#8217;ve discussed here.</p>
<p>In my experience, IoC containers become most powerful when integrated with an application framework that can auto-inject dependencies while requiring as little boilerplate as possible from the developer. Although this isn&#8217;t intended to be a sales-pitch, AngularJS has nicely integrated dependency injection and I recommend becoming familiar with its workflow even if just for the learning opportunity it provides.</p>
<h3>More Reading And Watching</h3>
<p>Check out this fantastic <a href="http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/" target="_blank">presentation by Miško Hevery</a> on why dependency injection is so important for clean and testable code. Seriously, don&#8217;t miss it.</p>
<p>If you&#8217;re the reading type, check out <a href="http://martinfowler.com/articles/injection.html#InversionOfControl" target="_blank">this article by Martin Fowler</a> for a more formal and authoritative description of inversion of control and dependency injection.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/general-programming/dependency-injection-and-ioc-containers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides: Intro To AngularJS</title>
		<link>http://aaronhardy.com/javascript/slides-intro-to-angularjs/</link>
		<comments>http://aaronhardy.com/javascript/slides-intro-to-angularjs/#comments</comments>
		<pubDate>Sat, 11 May 2013 03:02:23 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[angularjs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1460</guid>
		<description><![CDATA[Here are slides from a presentation I recently gave at Adobe on May 6, 2013. The examples linked to in the slides provided the basis for most of the discussion.]]></description>
				<content:encoded><![CDATA[<p>Here are slides from a presentation I recently gave at Adobe on May 6, 2013. The examples linked to in the slides provided the basis for most of the discussion.</p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/20680862" width="512" height="326" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/slides-intro-to-angularjs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides: JavaScript Patterns And Principles</title>
		<link>http://aaronhardy.com/javascript/slides-javascript-patterns-and-principles/</link>
		<comments>http://aaronhardy.com/javascript/slides-javascript-patterns-and-principles/#comments</comments>
		<pubDate>Sat, 11 May 2013 02:54:46 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[angularjs]]></category>
		<category><![CDATA[backbonejs]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[principles]]></category>
		<category><![CDATA[promise]]></category>
		<category><![CDATA[pubsub]]></category>
		<category><![CDATA[slides]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1452</guid>
		<description><![CDATA[As web applications grow increasingly more dynamic, software design patterns and principles become crucial for robustness and scalability. Let&#8217;s break out of the stigma of hodgepodge, spaghetti code found in web apps of old! In this presentation, we discussed modularity, communication patterns, and patterns used within MV* frameworks with examples from Backbone.js and AngularJS. These [...]]]></description>
				<content:encoded><![CDATA[<p>As web applications grow increasingly more dynamic, software design patterns and principles become crucial for robustness and scalability. Let&#8217;s break out of the stigma of hodgepodge, spaghetti code found in web apps of old! In this presentation, we discussed modularity, communication patterns, and patterns used within MV* frameworks with examples from <a href="http://backbonejs.org/" title="Backbone.js" target="_blank">Backbone.js</a> and <a href="http://angularjs.org/" target="_blank">AngularJS</a>.</p>
<p>These are slides from presentations I gave at Adobe on February 5, 2013 and April 30, 2013.</p>
<p><iframe src="http://www.slideshare.net/slideshow/embed_code/20437005" width="512" height="326" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/slides-javascript-patterns-and-principles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADC &amp; Appliness &#8211; Dependency Management with RequireJS</title>
		<link>http://aaronhardy.com/javascript/adc-appliness-dependency-management-with-requirejs/</link>
		<comments>http://aaronhardy.com/javascript/adc-appliness-dependency-management-with-requirejs/#comments</comments>
		<pubDate>Wed, 24 Oct 2012 02:22:52 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[amd]]></category>
		<category><![CDATA[dependency management]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[requirejs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1431</guid>
		<description><![CDATA[As if you haven&#8217;t had enough dependency management bi&#8217;niss from my recent Slides &#8211; Dependency Management with RequireJS and JavaScript Architecture: RequireJS Dependency Management posts, here&#8217;s similar material I&#8217;ve authored through other outlets: Adobe Developer Connection: Dependency Management with RequireJS Appliness: Dependency Management with RequireJS]]></description>
				<content:encoded><![CDATA[<p>As if you haven&#8217;t had enough dependency management bi&#8217;niss from my recent <a href="/javascript/dependency-management-with-requirejs/">Slides &#8211; Dependency Management with RequireJS</a> and <a href="http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/">JavaScript Architecture: RequireJS Dependency Management</a> posts, here&#8217;s similar material I&#8217;ve authored through other outlets:</p>
<p><a href="http://www.adobe.com/devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html" target="_blank">Adobe Developer Connection: Dependency Management with RequireJS</a><br />
<a href="http://appliness.com/code/Appliness-3-June.pdf" target="_blank">Appliness: Dependency Management with RequireJS</a</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/adc-appliness-dependency-management-with-requirejs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides &#8211; Dependency Management with RequireJS</title>
		<link>http://aaronhardy.com/javascript/dependency-management-with-requirejs/</link>
		<comments>http://aaronhardy.com/javascript/dependency-management-with-requirejs/#comments</comments>
		<pubDate>Mon, 22 Oct 2012 23:53:59 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[amd]]></category>
		<category><![CDATA[dependency management]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[requirejs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1421</guid>
		<description><![CDATA[Presented at 360&#124;Min 2012 in Las Vegas, NV.]]></description>
				<content:encoded><![CDATA[<p>Presented at 360|Min 2012 in Las Vegas, NV.<br />
<iframe src="http://www.slideshare.net/slideshow/embed_code/14841595" width="512" height="421" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/dependency-management-with-requirejs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript for the Flex Dev Slides</title>
		<link>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/</link>
		<comments>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/#comments</comments>
		<pubDate>Tue, 17 Apr 2012 02:02:04 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[backbonejs]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[requirejs]]></category>
		<category><![CDATA[underscorejs]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1351</guid>
		<description><![CDATA[Presented at 360&#124;Flex 2012 in Denver, Colorado.]]></description>
				<content:encoded><![CDATA[<p>Presented at <a href="http://www.360flex.com/" target="_blank">360|Flex</a> 2012 in Denver, Colorado.<br />
<iframe src="http://www.slideshare.net/slideshow/embed_code/12565929" width="512" height="421" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/javascript-for-flex-devs-slides/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JavaScript Architecture: RequireJS Dependency Management</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 02:35:23 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[amd]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[dependency management]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[requirejs]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[underscore.js]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1324</guid>
		<description><![CDATA[Updated Aug 11, 2012 to reflect current library versions. In JavaScript Architecture: Organization and Quality, we discussed the importance of breaking apps down into very small, decoupled pieces following the single responsibility principle. Small pieces are generally easier to comprehend than a mess of large peices. Some devs coming from other languages feel like they [...]]]></description>
				<content:encoded><![CDATA[<p><b>Updated Aug 11, 2012 to reflect current library versions.</b></p>
<p>In <a href="/javascript/javascript-architecture-organization-and-quality/">JavaScript Architecture: Organization and Quality</a>, we discussed the importance of breaking apps down into very small, decoupled pieces following the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank">single responsibility principle</a>. Small pieces are generally easier to comprehend than a mess of large peices.</p>
<p>Some devs coming from other languages feel like they can only build a few large, spaghetti JavaScript files for their app. I tend to think this may be caused by three reasons:</p>
<ul>
<li>That&#8217;s the way JavaScript has been done in the past.</li>
<li>Loading many JavaScript files requires many HTTP requests resulting in longer load times.</li>
<li>Dependency management is hard in JavaScript.</li>
</ul>
<p>Don&#8217;t stoop to these excuses. We can do better than that and today there are fantastic libraries and standards that can help us out.  However, let&#8217;s see what the above problems mean.<span id="more-1324"></span></p>
<p><strong>That&#8217;s the way JavaScript has been done in the past. </strong>Unfortunately, that&#8217;s true.  For years many teams developed within one or two large JavaScript files containing thousands of lines of code.  It goes without saying that maintainability was very poor.  It&#8217;s difficult to wrap our minds and <a href="http://en.wikipedia.org/wiki/Integrated_development_environment" target="_blank">IDEs</a> around thousand of lines of interoperating code and also a nightmare with version control in a team environment.  I do believe this is a large contributor to why JavaScript has had a bad wrap in the dev community for so long.</p>
<p><strong>Loading many JavaScript files requires many HTTP requests resulting in longer load times.</strong> It&#8217;s true. Each time a JavaScript file is loaded it requires the overhead of an inidiviual HTTP request and, unfortunately, if you list many script tags in your page the files will load in sequence, not in parallel.</p>
<p><strong>Dependency management is hard in JavaScript.  </strong>By splitting code out into many files, you must keep track of which files depend on each other and make sure they&#8217;re loaded in the right order.  This can be a messy long list and easy to mess up later down the line.  For example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script3.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script1.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script13.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script7.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script6.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script12.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script4.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script11.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script5.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script9.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script8.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script10.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>script src<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;script2.js&quot;</span><span style="color: #339933;">&gt;&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>This is troubling enough on a single-man project but even more-so within a team.</p>
<h2>Modules</h2>
<p>Let&#8217;s get nostalgic for a moment. A few years back, using JavaScript on the server-side was just starting to get hot. Server-side libraries and JavaScript engines were being deployed but they didn&#8217;t have a good, standard API for working with one another and defining dependencies. Getting one library to work with another required some finagling and it was obvious that if JavaScript were to scale it would need some common APIs.</p>
<p>In January 2009, Kevin Dangoor wrote a blog post titled <a href="http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/" target="_blank">What Server Side JavaScript Needs</a> outlining just that&#8211;what server-side JavaScript needed. The list included:</p>
<ul>
<li>Cross-interpreter standard library</li>
<li>Standard interfaces</li>
<li>Standard way to include other modules</li>
<li>Package up code for deployment and distribution</li>
<li>Install packages and their dependencies</li>
<li>Package repository</li>
</ul>
<p>As a means to fulfill these needs, he created a Google group named <a href="http://groups.google.com/group/commonjs" target="_blank">ServerJS</a> where like-minded folk could collaborate. Soon enough, the group realized that many of these goals weren&#8217;t necessarily limited to the server-side and renamed the group to <a href="http://www.commonjs.org/" target="_blank">CommonJS</a>.</p>
<p>One of the standards that CommonJS worked toward was that of a <a href="http://wiki.commonjs.org/wiki/Modules" target="_blank">module</a>.  A module is a contained piece of code (How&#8217;s that for vague?) that defines not only that it is a module itself but which other modules it depends on to correctly function.  When calling for module B, module B might call for module G and module M, which might call for modules D and W.  By having a module standard, dependency management becomes easier. Rather than keeping some sort of implicit master list that must be kept in order, each module just defines its own dependencies and that mapping can be used to determine required resources and the order in which they must be loaded.</p>
<h2>AMD</h2>
<p>The module concept was great for server-side development as it addressed how to synchronously load modules based on dependency definitions, but the JavaScript devs on the browser-side got a bit jealous.  Why should such awesomeness be confined to the server?  Sure, module loading needs to be done asynchronously in the browser, but that didn&#8217;t mean the concept of modules and dependency definitions couldn&#8217;t be applied.</p>
<p>The <a href="https://github.com/amdjs/amdjs-api/wiki/AMD" target="_blank">Asynchronous Module Definition</a>, or AMD, was born for this purpose. It takes the module and dependency definition API from the server-side and applies it to the asynchronous paradigm of the browser. </p>
<h2>RequireJS</h2>
<p>So what does <a href="http://requirejs.org/" target="_blank">RequireJS</a> have to do with this? Well, even though we can define our modules and their dependencies with AMD, we need something smart that can take this dependency map, load the modules, and execute the modules in order.  That&#8217;s the role RequireJS plays.  Both RequireJS and AMD are open source, popular, and well-curated by <a href="https://twitter.com/#!/jrburke" target="_blank">James Burke</a>.</p>
<h2>Defining and Requesting Modules</h2>
<p>At this point let&#8217;s jump straight into some code and hopefully the concepts will start to solidify.  Almost always, a module is defined within a single file and, vice-versa, a single file only contains a single module definition.  Defining a module, at its core, is as simple as the code below.  Let&#8217;s assume it&#8217;s within a file called book.js.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
    title<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;My Sister's Keeper&quot;</span><span style="color: #339933;">,</span>
    publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Atria&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>We now have a book module. <code>define()</code> is a RequireJS function.  When we call it, we&#8217;re essentially saying, &#8220;Register what I&#8217;m passing you as a module.&#8221;  By default, RequireJS assumes the module name is the file path following the base url (don&#8217;t get your panties in a twist&#8211;we&#8217;ll get to that in a minute) excluding the extension.  In this case, that means that &#8220;book&#8221; is our assumed module name.  When other code asks RequireJS for the &#8220;book&#8221; module, RequireJS will return the object we just defined above.  Now let&#8217;s make a &#8220;bookshelf&#8221; module in a new file named bookshelf.js and see how we can request the book module into it.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'book'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>book<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
		listBook<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			alert<span style="color: #009900;">&#40;</span>book.<span style="color: #660066;">title</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Notice this one&#8217;s a bit different than the book module.  The book module didn&#8217;t have any dependencies so it was a bit simpler.  Here, we&#8217;re defining an array of dependencies for our bookshelf&#8211;in this case, book.  The second parameter is a callback function.  If book.js hasn&#8217;t been loaded into the app yet, RequireJS will go fetch it from the server.  Once book.js is loaded and the book module is registered, RequireJS will execute our callback function and pass the module (the book object we defined previously) in as a parameter. The argument name isn&#8217;t technically significant.  We could have just as easily said <code>function(a1337Book)</code> or used whatever name we wanted.  In this case, it makes sense to have our argument name match the module name.  Whatever object we return from this callback function will be registered with RequireJS as the bookshelf module.  In our case, it&#8217;s an object with a <code>listBook()</code> method that alerts the book&#8217;s title.</p>
<p>RequireJS tries to be as efficient as possible when loading multiple modules. For example, if multiple dependencies are listed, RequireJS will load all the dependencies as fast as possible in parallel.</p>
<h2>App Setup</h2>
<p>So&#8230;how do we get this party started? Let&#8217;s first start by getting our html page set up. Here&#8217;s how it looks:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>RequireJS Example<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> data-main<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;js/main&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;js/libs/require.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>Quite literally, you can build a large application without adding anything else to your html file just by manipulating the body&#8217;s content using JavaScript and loading html snippets/templates using Require.  We&#8217;ll get there.  For now, take notice that there&#8217;s a <code>data-main</code> attribute.  This tells RequireJS where our bootstrap file is&#8211;in our case, it&#8217;s main.js that lives under a js directory (it assumes main has a js extension).</p>
<p>main.js is what we could call our bootstrap file. We&#8217;ll make ours look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'bookshelf'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookshelf<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	bookshelf.<span style="color: #660066;">listBook</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Because we specified this file as our <code>data-main</code> in our html file, RequireJS will load it as soon as possible and it will be immediately executed.  You&#8217;ll notice this has a lot of similarities to our previous modules but instead of calling <code>define()</code> it calls <code>require()</code>.  The <code>define()</code> function&#8211;at least when dependencies are defined&#8211;really does three things: (1) loads the dependencies specified, (2) calls the callback function once dependencies are loaded, and (3) registers the return value from the callback function as the module.  The <code>require()</code> function only does #1 and #2, not #3&#8211;hence the function names &#8220;define&#8221; vs. &#8220;require&#8221;.  In the case of main.js, it&#8217;s just a bootstrap file.  I don&#8217;t need to have a &#8220;main&#8221; module registered with RequireJS because nothing will be calling for it as a dependency.</p>
<p>Our bootstrap lists our &#8220;bookshelf&#8221; module as a dependency.  Assuming the bookshelf module hasn&#8217;t already been registered with RequireJS, it will load bookshelf.js.  Once it loads bookshelf.js, it will see that bookshelf has the book module listed as a dependency. If the book module hasn&#8217;t already been registered, it will then load book.js. Once that&#8217;s done and book and then bookshelf have registered their respective objects as modules with RequireJS, the callback in main.js will be executed and bookshelf will be passed through.  At that point we can do whatever we want with bookshelf.  If needed, we can list multiple module dependencies and they will all be passed into the callback as soon as they&#8217;re all loaded and registered with RequireJS.</p>
<h2>Configuration</h2>
<p>Previously I mentioned the concept of a base url.  By default, the base url is whatever directory contains the bootstrap file.  In my case, I put main.js under a js directory along with book.js and bookshelf.js.  This means, in my case, my base url is /js/.  Now let&#8217;s say instead of placing all my js files directly under the js directory, I moved book.js and bookshelf.js to /js/model/.  Now my main.js would need to look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'model/bookshelf'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookshelf<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	bookshelf.<span style="color: #660066;">listBook</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Now main knows the correct location of bookshelf.js.  Likewise, bookshelf.js would list the book dependency as <code>model/book</code> even though book and bookshelf live in the same directory.</p>
<p>This brings us to RequireJS configuration.  At the top of my bootstrap file, I usually perform my configuration. main.js might look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require.<span style="color: #660066;">config</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	baseUrl<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/another/path'</span><span style="color: #339933;">,</span>
	paths<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'myModule'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'a/b/c/d/myModule'</span>
		<span style="color: #3366CC;">'templates'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'../templates'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'text'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/text'</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'bookshelf'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookshelf<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	bookshelf.<span style="color: #660066;">listBook</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>In this case, I&#8217;ve manually changed my base url to something completely different.  Personally, I&#8217;ve never needed to configure this but it&#8217;s there to demonstrate one of the <a href="http://requirejs.org/docs/api.html#config" target="_blank">many configuration options available</a>.  I also demonstrated how to configure paths.  Paths are really just shortcuts.  In this case, rather than having to type out &#8220;a/b/c/d/myModule&#8221; when listing dependencies, I can just type &#8220;myModule&#8221;.  I&#8217;ve set up a path (shortcut) for accessing a templates directory that is a sibling to my js directory.  I&#8217;ve also set up a path (shortcut) for accessing the RequireJS <a href="http://requirejs.org/docs/api.html#text" target="_blank">text! plugin</a> more easily.</p>
<h2>Class Modules</h2>
<p>So far, our modules have all been object instances; bookshelf was an object and book was an object.  In reality, modules are very often classes. When using Backbone, modules are classes much more often than not.  The bookshelf <i>class</i> needs the book <i>class</i>, for instance.  It can then instantiate a bunch of books or whatever it needs to do using the book class.  If an instance of the class needs to be passed to different <a href="/javascript/javascript-architecture-backbone-js-views/">Backbone views</a>, for example, it would be passed through the recipient view&#8217;s constructor or other method.  You&#8217;ll start to see that listing dependencies is similar to listing imports in languages like Java or ActionScript.  It&#8217;s essentially giving you access to another class that you can then use within the class you&#8217;re defining.  You just so happen have the ability to also define and retrieve object instances as modules if you really want to. Hopefully this will become more obvious in the next example.</p>
<h2>RequireJS + Backbone</h2>
<p>Using the knowledge from the previous articles in this series and our new-found knowledge of modules, let&#8217;s see an integrated example.  In essence, we have a collection of book models.  We&#8217;re calling the collection a bookshelf.  We have a bookshelf view that loops through the books in the bookshelf, creating a book view for each book in the bookshelf.  The book view displays information about the book.  The views, frankly, are over-architected for the simple stuff we&#8217;re doing here, but I think this demonstrates the integration of RequireJS and Backbone nicely.  If it&#8217;s still unclear, please post a comment and I&#8217;ll do my best to answer.</p>
<p>index.html:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>RequireJS Example<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> data-main<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;js/main&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;js/libs/require.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>js/main.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require.<span style="color: #660066;">config</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #3366CC;">'paths'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'jquery'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/jquery'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/backbone'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/underscore'</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	shim<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// These script dependencies should be loaded </span>
			<span style="color: #006600; font-style: italic;">// before loading backbone.js</span>
			deps<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'jquery'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			<span style="color: #006600; font-style: italic;">// Once loaded, use the global 'Backbone' </span>
			<span style="color: #006600; font-style: italic;">// as the module value.</span>
			exports<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Backbone'</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// Use the global '_' as the module value.</span>
			exports<span style="color: #339933;">:</span> <span style="color: #3366CC;">'_'</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
require<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'view/bookshelf-view'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>BookshelfView<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">new</span> BookshelfView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
			el<span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>js/view/bookshelf-view.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'model/bookshelf'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'view/book-view'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>Backbone<span style="color: #339933;">,</span> _<span style="color: #339933;">,</span> Bookshelf<span style="color: #339933;">,</span> BookView<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">collection</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Bookshelf<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
				<span style="color: #009900;">&#123;</span>
					title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'A Tale of Two Cities'</span><span style="color: #339933;">,</span>
					author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Charles Dickens'</span>
				<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
				<span style="color: #009900;">&#123;</span>
					title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'The Good Earth'</span><span style="color: #339933;">,</span>
					author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Pearl S. Buck'</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
		render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">collection</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>book<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">var</span> bookView <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> BookView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					model<span style="color: #339933;">:</span> book
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
				<span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>bookView.$el<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>js/view/book-view.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'underscore'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>Backbone<span style="color: #339933;">,</span> _<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
		render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Title: '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span>
					<span style="color: #3366CC;">'; Author: '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'author'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>js/model/bookshelf.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'model/book'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>Backbone<span style="color: #339933;">,</span> Book<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> Backbone.<span style="color: #660066;">Collection</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		model<span style="color: #339933;">:</span> Book
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>js/model/book.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'backbone'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>Backbone<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> Backbone.<span style="color: #660066;">Model</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #006600; font-style: italic;">// Intended attributes:</span>
		<span style="color: #006600; font-style: italic;">// title</span>
		<span style="color: #006600; font-style: italic;">// author</span>
		<span style="color: #006600; font-style: italic;">// genre</span>
&nbsp;
		defaults<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
			genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'historical'</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<div class="goodies"><a href="http://code.aaronhardy.com/require-backbone" target="_blank">View Demo</a><br class="break"></div>
<h2>Loading Non-Modules</h2>
<p>Some libraries you want to use in your project don&#8217;t conform to the AMD spec.  In fact, Backbone and Underscore have had their <a href="https://github.com/documentcloud/backbone/pull/710" target="_blank">flirts with conforming to AMD</a> but, at the moment of this writing, aren&#8217;t AMD modules.  Backbone has no concept of modules, dependency loading, RequireJS, or any of that.  It just sets a global variable called <code>Backbone</code> and expects you to use it. This means if we were to just add the backbone.js file to our project and list Backbone as a dependency from one of our modules, it wouldn&#8217;t work.  RequireJS will load backbone.js, but nothing in backbone.js registers itself as a module with RequireJS.  RequireJS will throw up its hands and say something like, &#8220;Well, I loaded the file, but I didn&#8217;t find any module in there.&#8221;</p>
<p>For this reason, RequireJS has provided us the ability to specify a <a href="http://requirejs.org/docs/api.html#config-shim" target="_blank">&#8220;shim&#8221; configuration</a> which you can see in the example above.  I&#8217;ll repeat it here:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require.<span style="color: #660066;">config</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	...
&nbsp;
	<span style="color: #660066;">shim</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// These script dependencies should be loaded</span>
			<span style="color: #006600; font-style: italic;">// before loading backbone.js</span>
			deps<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'jquery'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			<span style="color: #006600; font-style: italic;">// Once loaded, use the global 'Backbone'</span>
			<span style="color: #006600; font-style: italic;">// as the module value.</span>
			exports<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Backbone'</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006600; font-style: italic;">// Use the global '_' as the module value.</span>
			exports<span style="color: #339933;">:</span> <span style="color: #3366CC;">'_'</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Like the comments say, for Backbone we need to make sure underscore and jQuery are loaded first since they are dependencies of Backbone (that&#8217;s the <code>deps</code> part) and then we&#8217;ll make the global <code>Backbone</code> variable act like a module (that&#8217;s the exports part).  Underscore doesn&#8217;t have any dependencies but it&#8217;s not AMD compatible so we&#8217;ve configured the global variable <code>_</code> to act like a module.</p>
<p>Now, we don&#8217;t <i>always</i> have to make everything act like a module. Let&#8217;s say we just want to load a single non-AMD JavaScript library file we downloaded off the web. It doesn&#8217;t depend on anything else and we don&#8217;t want to set up a shim for it for whatever reason.  We just want to make sure the file is loaded and then just access the global variable like we normally would if we weren&#8217;t using RequireJS.  That&#8217;s not a problem; we can load it in and access it using the global variable. Here&#8217;s an example of how we would do so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'js/libs/coolLib.js'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span>window.<span style="color: #660066;">coolLib</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>A few things to notice here: First, our path to the file includes everything from the directory where our html file is located.  This is unlike loading a module which would include everything after our &#8220;base url&#8221; (read above if you don&#8217;t remember what this is).  Second, our path includes the file extension.  This is unlike loading a module which would exclude the extension.  Third, because it&#8217;s not a module, RequireJS won&#8217;t pass anything into our callback function.   At that point we just reference coolLib however the coolLib library dictates. RequireJS is just loading the file and, once it&#8217;s loaded, calls our callback function.  Nothing special.</p>
<h2>Loading Templates</h2>
<p>Back in <a href="/javascript/javascript-architecture-underscore-js/">JavaScript Architecture: Underscore.js</a>, we discussed how to break our HTML into templates to prevent it from mingling too closely with our JavaScript.  In the examples we used, we put our HTML templates within script tags.  I then posed the question, &#8220;You might rightfully be wondering how this is scalable if you start to have hundreds of templates in your html file or how you might be able to load them asynchronously only when needed.&#8221;  This is also where RequireJS helps out.</p>
<p>RequireJS has a nice plugin called text!.  You might think I&#8217;m really excited about it because I put an exclamation point next to it. While I do admit it&#8217;s pretty south-beach sexy, really that&#8217;s just the nomenclature of RequireJS plugins because you type something like &#8220;text!myTemplate&#8221; when using them.  The text! plugin allows us to load in files of text&#8211;in our case, HTML templates.  Let&#8217;s see how this works.</p>
<p>First we&#8217;ll <a href="http://requirejs.org/docs/api.html#text" target="_blank">download</a> and place the text! plugin file in js/libs.</p>
<p>We&#8217;ll place book.tpl.html located under a templates directory that&#8217;s a sibling to our js directory:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span>&gt;</span>Title:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;value&quot;</span>&gt;&lt;%<span style="color: #66cc66;">=</span> <span style="color: #000066;">title</span> %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span>&gt;</span>Author:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;value&quot;</span>&gt;&lt;%<span style="color: #66cc66;">=</span> author %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span><span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;label&quot;</span>&gt;</span>Genre:<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">span</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;value&quot;</span>&gt;&lt;%<span style="color: #66cc66;">=</span> genre %&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;</span></pre></td></tr></table></div>

<p>Add some paths to our RequireJS configuration in our main.js to make it easier to use in our modules:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">require.<span style="color: #660066;">config</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #3366CC;">'paths'</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">'jquery'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/jquery'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/backbone'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/underscore'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'templates'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'../templates'</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">'text'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'libs/text'</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Then use the template in book-view.js:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">define<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>
	<span style="color: #3366CC;">'backbone'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'underscore'</span><span style="color: #339933;">,</span>
	<span style="color: #3366CC;">'text!templates/book.tpl.html'</span>
<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>Backbone<span style="color: #339933;">,</span> _<span style="color: #339933;">,</span> template<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">return</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		_template<span style="color: #339933;">:</span> _.<span style="color: #660066;">template</span><span style="color: #009900;">&#40;</span>template<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
&nbsp;
		initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
		render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>._template<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #660066;">toJSON</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<div class="goodies"><a href="http://code.aaronhardy.com/require-backbone-template" target="_blank">View Demo</a><br class="break"></div>
<p>Notice that the template argument is a string variable holding the exact html as found in our template html file.  Then, we use underscore to convert it to a compiled template. We run our book model attributes through the template on <code>render()</code>.  Finally, we update our element&#8217;s inner html with the result.</p>
<p>So what about all those potential HTTP requests?  Here&#8217;s where we optimize&#8230;</p>
<h2>Optimization</h2>
<p>We&#8217;ve broken down all our JavaScript and HTML into granular pieces.  Now we potentially have hundreds of files and unless we do some optimization we would be making hundreds of HTTP requests.  Fortunately, we can leverage the <a href="http://requirejs.org/docs/optimization.html" target="_blank">RequireJS optimizer</a>.</p>
<p>Generally, you set up the optimizer to run on your server before deploying code. The RequireJS optimizer takes your app files, minifies them (shortens your code to make the files really small), and then concatenates them (smashes them together to make a single file).  In the end, you end up with a single file that contains both your JavaScript and your HTML templates. After index.html loads RequireJS, it will load our main.js file.  Our main.js file, this time, will not only contain our expected main.js code but all the minified, concatenated code of the rest of our app&#8211;both JavaScript and HTML templates.  Everything in the file will register itself with RequireJS.  When main starts asking for dependencies and those dependencies start asking for dependencies, RequireJS will recognize that all those modules have already been loaded and forego loading them again.</p>
<p>The optimizer has a smattering of options.  You can optimize your app down to a few different files representing sections of your app instead of a single large file.  You can also use different minifier libraries, exclude files from concatenation, or even minify CSS.</p>
<h2>Learn More</h2>
<p>We&#8217;ve covered a lot of content but there&#8217;s plenty more to learn about dependency management.  I&#8217;ve written <a href="http://www.adobe.com/devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html" target="_blank">a separate article on the Adobe Developer Connection</a> that might catch your interest.  Also, the <a href="http://requirejs.org/" target="_blank">RequireJS website</a> is a great place to start.  If you&#8217;re interested in seeing more examples of Backbone + RequireJS, dig into this <a href="http://addyosmani.github.com/todomvc/dependency-examples/backbone_require/index.html" target="_blank">Todos App example</a>.  And, as always, feel free to provide feedback or ask questions below!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-requirejs-dependency-management/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Backbone.js Routers</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-routers/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-routers/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 06:22:16 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[hashbang]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[pushState]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[single-page app]]></category>
		<category><![CDATA[SPA]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1290</guid>
		<description><![CDATA[Updated Aug 11, 2012 to reflect current library versions. In JavaScript Architecture: Backbone.js Views we discussed how to build dynamic apps that change views on the fly using JavaScript. Because view-switching is done without reloading the page or transferring control to a separate page, these are called single-page applications. Single-page applications pose a few issues [...]]]></description>
				<content:encoded><![CDATA[<p><b>Updated Aug 11, 2012 to reflect current library versions.</b></p>
<p>In <a href="/javascript/javascript-architecture-backbone-js-views/">JavaScript Architecture: Backbone.js Views</a> we discussed how to build dynamic apps that change views on the fly using JavaScript.  Because view-switching is done without reloading the page or transferring control to a separate page, these are called <a href="http://en.wikipedia.org/wiki/Single-page_application" target="_blank">single-page applications</a>.  Single-page applications pose a few issues we need to address:</p>
<ul>
<li>When users hit their browser&#8217;s back button, they will be taken away from the app completely rather than back to a previous view within the app itself.</li>
<li>Users are only able to link to or bookmark the app itself&#8211;not a specific view within the app.</li>
<li>Deep views within the app may not be crawlable by search engines.</li>
</ul>
<p>We want a great experience for our users.  Successful apps behave as users would logically expect and users should feel like they can easily navigate back to where they were previously.</p>
<p>Like the topics we&#8217;ve addressed before, these issues aren&#8217;t specific to Backbone. It&#8217;s an issue that naturally arises in any single-page app. Fortunately, Backbone does a great job at addressing it and has a simple API.<span id="more-1290"></span></p>
<h3>Examples</h3>
<p>This concept is most easily taught by example so let&#8217;s assume we&#8217;re building an app that sells shirts. We&#8217;ve built it out so we show a grid of shirt images and when the user clicks on a shirt, a panel slides out that covers half of the window and contains more details regarding that specific shirt. Without some extra work, if users are on this extra details view and click the back button in the browser, they will be taken out of the app completely rather than just hiding the extra details view.  This is because, technically, the details view is not a new html page&#8211;it&#8217;s just another &#8220;view&#8221; within the same html page.</p>
<p>The browser has no concept of views that are changing within your app and therefore cannot automatically register history steps in this regard. As we discussed in <a href="http://aaronhardy.com/javascript/javascript-architecture-backbone-js-views/" target="_blank">JavaScript Architecture: Backbone.js Views</a>, the definition and granularity of a view can become very blurry. For example, if we pop up a settings panel after a user clicks on a gear icon, does the settings panel merit a history step in the browser so that if the user clicks the back button the panel closes? As much as we would like browsers to figure this out automatically, it&#8217;s really a user experience judgement call on our part and we must tell the browser when to register a new history step. This gives us a lot of power.</p>
<p>For starters, let&#8217;s take a look at a simple example with Backbone:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
		&lt;title&gt;Backbone Example&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;script src=&quot;js/libs/jquery.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/underscore.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/backbone.js&quot;&gt;&lt;/script&gt;
		<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
			$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">var</span> AppRouter <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Router</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					routes<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #3366CC;">&quot;shirt/id/:id&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;showShirt&quot;</span>
					<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
					showShirt<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Show shirt with id '</span> <span style="color: #339933;">+</span> id <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> appRouter <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> AppRouter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				Backbone.<span style="color: #660066;">history</span>.<span style="color: #660066;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
		&lt;a href=&quot;#shirt/id/5&quot;&gt;Shirt with id of 5&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#shirt/id/10&quot;&gt;Shirt with id of 10&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#shirt/id/15&quot;&gt;Shirt with id of 15&lt;/a&gt;&lt;br&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<div class="goodies"><a href="http://code.aaronhardy.com/backbone-router-single-param/" target="_blank">View Demo</a><br class="break"></div>
<p>You can see we have three links each linking to a shirt with a different id.  Notice that the pound sign at the beginning of each link url (e.g., #shirt/id/5) is important as it tells the browser we&#8217;re neither moving to a new html page nor refreshing the current page.  It&#8217;s formally known as a <a href="http://en.wikipedia.org/wiki/Fragment_identifier" target="_blank">fragment identifier</a> and has been a web standard for quite a while.  </p>
<p>In our example, We&#8217;ve also set up a backbone router with &#8220;routes&#8221; which are essentially url patterns that are meaningful to our app.  In this case, we have set up a single route, <code>shirt/id/:id</code>, with a handler of <code>showShirt()</code>.  The <code>:id</code> portion is called a parameter part.  If a user navigates to the url <code>&lt;current_page&gt;/#shirt/id/123123</code>, the fragment would qualify as a match and the id (123123) would be passed as a parameter to the <code>showShirt()</code> function. In our example, if the user clicks the first link we set up, the url will be changed to <code>&lt;current_page&gt;/#shirt/id/5</code> and Backbone will subsequently call <code>showShirt(5)</code>.</p>
<p>To have a little fun, let&#8217;s go nuts for donuts and get crazy up in here:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
		&lt;title&gt;Backbone Example&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;script src=&quot;js/libs/jquery.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/underscore.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/backbone.js&quot;&gt;&lt;/script&gt;
		<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
			$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">var</span> AppRouter <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Router</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					routes<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #3366CC;">&quot;:product/:attribute/:value&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;showProduct&quot;</span>
					<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
					showProduct<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>product<span style="color: #339933;">,</span> attribute<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Show '</span> <span style="color: #339933;">+</span> product <span style="color: #339933;">+</span> <span style="color: #3366CC;">' where '</span> <span style="color: #339933;">+</span> attribute <span style="color: #339933;">+</span> <span style="color: #3366CC;">' = '</span> <span style="color: #339933;">+</span> value <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> appRouter <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> AppRouter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				Backbone.<span style="color: #660066;">history</span>.<span style="color: #660066;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
		&lt;a href=&quot;#shoe/size/12&quot;&gt;Size 12 shoes&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#shirt/id/5&quot;&gt;Shirt with id of 15&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#hat/color/black&quot;&gt;Black hats&lt;/a&gt;
	&lt;/body&gt; 
&lt;/html&gt;</pre></td></tr></table></div>

<div class="goodies"><a href="http://code.aaronhardy.com/backbone-router-multi-param/" target="_blank">View Demo</a><br class="break"></div>
<p>This time we set up our route with three parameter parts.  Because there are three parameter parts, three parameters will be passed into <code>showProduct()</code>.  Easy enough.</p>
<h3>Deep-linking</h3>
<p>Now that we have our routes set up, we can <a href="http://en.wikipedia.org/wiki/Deep_linking" target="_blank">deep-link</a> to a specific view within our app.  For example, a user might click on the size 12 shoes link which changes the url in their browser to <a href="http://code.aaronhardy.com/backbone-router-multi-param/#shirt/id/5" target="_blank">http://code.aaronhardy.com/backbone-router-multi-param/#shirt/id/5</a>.  The user may want to share that shirt with a friend so they copy the link and send it in an email.  When the user clicks on the link, the app loads, and backbone sees that the url already matches a route.  <code>showProduct()</code> will then be automatically called which will immediately show the product details panel to the user.  Go ahead, click on the link above and see the concept in action.</p>
<h3>Showing requested content</h3>
<p>In the above examples we&#8217;re just alerting information about the parameter parts.  In a real app, the user would expect the app to switch to an appropriate view and load appropriate data. How you handle going from the <code>showProduct()</code> function to switching views has been left up to you.  However, one option is, rather than calling a function within the router itself, views can watch the router for <code>route</code> events and update themselves accordingly:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
		&lt;title&gt;Backbone Example&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;script src=&quot;js/libs/jquery.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/underscore.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;js/libs/backbone.js&quot;&gt;&lt;/script&gt;
		<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
			$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">var</span> AppRouter <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Router</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					routes<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #3366CC;">&quot;:product/:attribute/:value&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;showProduct&quot;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> appRouter <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> AppRouter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> MyView <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						options.<span style="color: #660066;">router</span>.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'route:showProduct'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>product<span style="color: #339933;">,</span> attribute<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
							alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Update to show '</span> <span style="color: #339933;">+</span> product <span style="color: #339933;">+</span> <span style="color: #3366CC;">' where '</span> <span style="color: #339933;">+</span> attribute <span style="color: #339933;">+</span> <span style="color: #3366CC;">' = '</span> <span style="color: #339933;">+</span> value <span style="color: #339933;">+</span> <span style="color: #3366CC;">'.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				window.<span style="color: #660066;">myView</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> MyView<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>router<span style="color: #339933;">:</span> appRouter<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				Backbone.<span style="color: #660066;">history</span>.<span style="color: #660066;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
		&lt;a href=&quot;#shoe/size/12&quot;&gt;Size 12 shoes&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#shirt/id/5&quot;&gt;Shirt with id of 5&lt;/a&gt;&lt;br&gt;
		&lt;a href=&quot;#hat/color/black&quot;&gt;Black hats&lt;/a&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<div class="goodies"><a href="http://code.aaronhardy.com/backbone-router-view-switching/" target="_blank">View Demo</a><br class="break"></div>
<p>Another option is to share a <a href="/javascript/javascript-architecture-backbone-js-models/">backbone model</a> amongst the router and views.  The router can then set a property on the model and the views can then respond to change events coming from the model.</p>
<h3>Fragment identifier vs. pushState</h3>
<p>Using fragment identifiers (#) or hashbangs/shebangs (#!) in the manner described above or as used by Twitter (<a href="https://twitter.com/#!/Aaronius" target="_blank">https://twitter.com/#!/Aaronius</a>), Grooveshark (<a href="http://grooveshark.com/#!/artist/Gotye/49212" target="_blank">http://grooveshark.com/#!/artist/Gotye/49212</a>), or GMail (<a href="https://mail.google.com/mail/ca/#label/isys" target="_blank">https://mail.google.com/mail/ca/#label/isys</a>) doesn&#8217;t come without <a href="http://danwebb.net/2011/5/28/it-is-about-the-hashbangs" target="_blank">controversy</a>, <a href="http://www.adequatelygood.com/2011/2/Thoughts-on-the-Hashbang" target="_blank">controversy</a>, and <a href="http://blog.utest.com/hashbangs-the-future-of-urls-or-the-end-of-the-internet/2011/06/" target="_blank">more controversy</a>.</p>
<p>In the end, the answer to the controversy is to use the new <a href="http://www.w3.org/TR/html5/history.html" target="_blank">HTML5 History</a> (more commonly known as pushState) standard that allows us to <a href="http://diveintohtml5.info/history.html" target="_blank">change the browser url and manage history steps without using fragment identifiers or forcing a page refresh on the user</a>.  The biggest roadblock to this new standard is obtaining <a href="http://diveintohtml5.info/history.html#how" target="_blank">browser support</a>, particularly Internet Explorer support.  For browsers that don&#8217;t support HTML5 History, a fallback must be available which usually entails page refreshes as the user navigates through the app.</p>
<p>Once you&#8217;re ready to support pushState, you&#8217;ll be glad to know Backbone supports it on an opt-in basis.  Read more about how to <a href="http://documentcloud.github.com/backbone/#History" target="_blank">set up Backbone for pushState</a>.</p>
<h3>More Juiciness</h3>
<p>Backbone&#8217;s <a href="http://documentcloud.github.com/backbone/#Router" target="_blank">router</a> and <a href="http://documentcloud.github.com/backbone/#History" target="_blank">history</a> have even more options and features so I suggest you check out their respective documentation.  Thanks for reading and, as always, feel free to post a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-routers/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Backbone.js Views</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-views/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-views/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 05:41:02 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[className]]></category>
		<category><![CDATA[collection]]></category>
		<category><![CDATA[delegateEvents]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[el]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[id]]></category>
		<category><![CDATA[isolation]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[render]]></category>
		<category><![CDATA[tagName]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1250</guid>
		<description><![CDATA[Updated Aug 11, 2012 to reflect current library versions. Tech-agnostic concepts At this point of the series I really want to emphasize that the core concepts I&#8217;ve explained and will explain are not unique to Backbone; they&#8217;re unique to apps with state and dynamic views. I&#8217;m merely using Backbone as an illustration of a concrete [...]]]></description>
				<content:encoded><![CDATA[<p><b>Updated Aug 11, 2012 to reflect current library versions.</b></p>
<h3>Tech-agnostic concepts</h3>
<p>At this point of the series I really want to emphasize that the core concepts I&#8217;ve explained and will explain are not unique to Backbone; they&#8217;re unique to apps with state and dynamic views.  I&#8217;m merely using Backbone as an illustration of a concrete tool that can be used to solve problems common to this type of app in general.  The concept of &#8220;views&#8221; is no different.</p>
<h3>What is a view?</h3>
<p>If you&#8217;re coming from a different language or even a different library, you may be familiar with words like component, widget, or control. You can ask 10 engineers what they think those terms mean and you&#8217;ll likely get 10 different answers&#8230;or 30 if they think the terms are different from each other.  The term view is just another one to throw on the pile and is equally ambiguous.  It&#8217;s not all that unfortunate.  Indeed, its usage can be quite flexible and its granularity disparate.</p>
<p>In the traditional web of requesting a new page for each section of a website, we may consider each page a view. Indeed, it is. In modern apps, it&#8217;s more common to have a single page and, as the user interacts with the page, portions of the page change.  Those dynamic portions could likewise be called views.  Within a dynamic portion of the page, there may be a toolbar that affects a list of customers.  The toolbar could be considered a view.  The list of customers could be another view.  Each customer row inside the list of customers may be its own view.  The row may contain a toggle button which is yet another view.  The point is, in the Backbone world, the term view doesn&#8217;t necessary mean &#8220;a section of your website&#8221;.  It can be, and oftentimes should be, much more granular than that.<span id="more-1250"></span></p>
<p>At a technical level, a Backbone view is simply a JavaScript object that manages a specific DOM element and its descendants.  If view A manages DOM element A and its descendants, no other view should touch DOM element A or its descendants.  That&#8217;s view A&#8217;s domain.  If you want to change the DOM elements of view A, go through view A&#8217;s API.</p>
<p>That said, a view can have sub views.  In the example above, I mentioned a list of customers being a view and each customer row being a view.  The customer row owns its DOM elements.  The parent list view should not touch DOM elements within the customer row view.  Is there a model the row should render?  Pass the model to the customer row view.  At that point, it&#8217;s the row view&#8217;s job. Throw it over the wall and forget about it.</p>
<p>With jQuery you&#8217;ll be heavily tempted to just change elements anywhere on the page willy-nilly because it&#8217;s so easy.  It&#8217;s the fastest way to accomplish your task before the demo with your boss that starts in five minutes.  The unfortunate truth is that structure, robustness, and scalability are not the easiest path in the short-term.  In the long-term, though, they are absolutely critical to the success and future of the product and ultimately <em>will</em> establish the easiest path.</p>
<h3>View granularity</h3>
<p>So how granular should a view be? You&#8217;ll be hard-pressed to find a definite answer but here are a few guidelines.  Is your view getting bloated with hundreds of lines of code? Try to break it up into smaller views.  Is a single view accomplishing multiple, unrelated tasks (termed as having <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank">low cohesion</a>)?  Break it up into smaller views with distinct tasks.  Do you find yourself wanting to copy-paste a portion of a view into other views?  That portion should likely be its own view.  Does your view manage a single DOM element that has no DOM descendants and is very simple like a single html link?  It can likely be safely merged up with the parent view.  When in doubt, choose many small views over a few large ones.</p>
<p>For you visual learners, take my current Twitter feed as an example.  Look around this page and think about how you might divide it up into views and why.</p>
<p><a href="http://aaronhardy.com/wp-content/uploads/2012/01/backbone-views-no-lines.gif" target="_blank"><img src="http://aaronhardy.com/wp-content/uploads/2012/01/backbone-views-no-lines-300x242.gif" alt="" title="Backbone Views No Hints" width="300" height="242" class="alignleft size-medium wp-image-1257" /></a></p>
<p>I&#8217;m not going to tell you there&#8217;s a right answer, but here&#8217;s an idea of how I might divide it up:</p>
<p><a href="http://aaronhardy.com/wp-content/uploads/2012/01/backbone-views.gif"><img src="http://aaronhardy.com/wp-content/uploads/2012/01/backbone-views-300x242.gif" alt="" title="Backbone View Hints" width="300" height="242" class="alignleft size-medium wp-image-1286" /></a></p>
<h3>View isolation and synchronization</h3>
<p>We&#8217;ve talked about eventful <a href="/javascript/javascript-architecture-backbone-js-models/" target="_blank">models</a> and <a href="/javascript/javascript-architecture-backbone-js-collections/" target="_blank">collections</a> and how they can be used to synchronize and drive multiple views without the views having to be aware of each other.  The idea of view isolation and <a href="http://en.wikipedia.org/wiki/Black_box" target="_blank">black-boxing</a> is a very, very critical concept.  So important we&#8217;re going to cover it again.</p>
<p>Let&#8217;s take a closer look at my Twitter feed.  Let&#8217;s say I put my cursor in the &#8220;What&#8217;s happening?&#8221; textarea, type my tweet, then hit the tweet button.  What should happen at that moment on the page?</p>
<ol>
<li>My number of tweets on the right side of the page should be incremented.</li>
<li>My tweet should be added to my timeline.</li>
<li>The &#8220;What&#8217;s happening?&#8221; textarea should be cleared.</li>
</ol>
<p>While coding the event handler for the tweet button, it&#8217;d be really easy to just say, &#8220;Well, I know the id of the tweet count DOM element. I&#8217;ll just grab the element using jQuery and increment the number inside it.&#8221;  What&#8217;s wrong with this?  We just reached outside our view and manipulated the DOM element of another view.  Like I&#8217;ve said before, this will lead to a giant web of dag-nasty in the long run.  Avoid it.  In fact, avoid forcing the two views to know about each other at all.</p>
<p>Instead, let&#8217;s create a model that contains the number of tweets.  Both the &#8220;What&#8217;s happening?&#8221; view and the tweet count view share the model.  When the user clicks the tweet button, we increment the number on the model.  The tweet count view will be notified by the model that the number of tweets has changed.  The tweet count view will then update its DOM element.  The views can carry on blissfully unaware of each other.</p>
<p>Likewise, we can have a collection containing the tweets that should show up in our timeline.  We add a tweet model to the collection from the &#8220;What&#8217;s happening?&#8221; view and the collection notifies the timeline view of the addition. The timeline view creates a single tweet view, shoves the tweet model into the tweet view, then adds the tweet view&#8217;s DOM element as the first child of the timeline&#8217;s DOM element.  This last part will hopefully make more sense later, but notice the timeline does not know how the tweet view is showing the tweet or what its DOM element contains. It doesn&#8217;t care.  It just throws the model over the wall.</p>
<h3>View properties</h3>
<p>Okay, let&#8217;s get to the meat.  Backbone views have several special properties you should know about:</p>
<ul>
<li><code>el</code> &#8211; Each view has a DOM element it is managing. <code>el</code> is a reference to this DOM element.  It can be set from the parent or it can be created and set from within the view itself.</li>
<li><code>$el</code> &#8211; A jQuery-wrapped version of <code>el</code>.
<li><code>id</code> &#8211; If the view automatically creates a DOM element because <code>el</code> wasn&#8217;t set through the constructor, the automatically-created DOM element will receive an id as specified by the <code>id</code> property.</li>
<li><code>model</code> &#8211; Each view will likely be dealing with a model specified using the <code>model</code> property.</li>
<li><code>collection</code> &#8211; Or the view will be dealing with a collection specified using the <code>collection</code> property.</li>
<li><code>tagName</code> &#8211; During instantiation, the view will determine if <code>el</code> was set through the constructor.  If it wasn&#8217;t, the view will automatically create an element and will set it as the value for the <code>el</code> property.  The type of element the view will automatically create is determined by <code>tagName</code>.  By default, <code>tagName</code> is set to <code>div</code>, meaning the view will create a div element and set it as the <code>el</code> property if <code>el</code> wasn&#8217;t set through the constructor.</li>
<li><code>className</code> &#8211; If the view automatically creates a DOM element because <code>el</code> wasn&#8217;t set through the constructor, the automatically-created DOM element will receive a CSS class name as specified by the <code>className</code> property.</li>
</ul>
<p>What&#8217;s so special about these properties?  Let&#8217;s take a look:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> TweetRow <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'I can access this.model directly! '</span> <span style="color: #339933;">+</span>
				<span style="color: #3366CC;">'The tweet text is '</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'I can only access my notSoSpecialProp through options: '</span> <span style="color: #339933;">+</span>
				options.<span style="color: #660066;">notSoSpecialProp</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'I didn<span style="color: #000099; font-weight: bold;">\'</span>t even pass in el but the view made a '</span> <span style="color: #339933;">+</span>
				<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span>.<span style="color: #660066;">tagName</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' for me!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> tweet <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	avatar<span style="color: #339933;">:</span> <span style="color: #3366CC;">'aaronius.jpg'</span><span style="color: #339933;">,</span>
	alias<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Aaronius'</span><span style="color: #339933;">,</span>
	text<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Honey roasted peanuts rock my sox.'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TweetRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	model<span style="color: #339933;">:</span> tweet<span style="color: #339933;">,</span>
	notSoSpecialProp<span style="color: #339933;">:</span> <span style="color: #CC0000;">42</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Here I passed in an options object into my tweet row view. The options object is passed into the <code>initialize()</code> method which is automatically called by <code>Backbone.View</code>. Behind the scenes, though, the view first takes the special properties in the options object and merges them as first-class properties of the view.  Now we can access them directly (e.g., <code>this.model</code>, <code>this.el</code>).  On the other hand, anything that&#8217;s not considered special by the view is only accessible through the options object itself; they aren&#8217;t merged to the view as direct properties.</p>
<h3>Rendering</h3>
<p>Now we have a model or collection we&#8217;re dealing with (<code>this.model</code> or <code>this.collection</code>) and also a DOM element we&#8217;re managing (<code>this.el</code>).  Now it&#8217;s time to render something.  In <a href="/javascript/javascript-architecture-underscore-js/" target="_blank">JavaScript Architecture: Underscore.js</a> we talked about how to use templates to render pieces of UI.  Let&#8217;s take a look at how we would use our model and template to render a tweet row.  In this example, I&#8217;m going to include the full HTML file I&#8217;m working with.  This is far from a fully baked app, but I want you to get your hands on something that will actually run in a browser:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
		&lt;title&gt;Backbone Example&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;script src=&quot;libs/jquery.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;libs/underscore.js&quot;&gt;&lt;/script&gt;
		&lt;script src=&quot;libs/backbone.js&quot;&gt;&lt;/script&gt;
		<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
			$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">var</span> TweetRow <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					_template<span style="color: #339933;">:</span> _.<span style="color: #660066;">template</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#tweet-row-template'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
&nbsp;
					initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
					render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>._template<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">model</span>.<span style="color: #660066;">toJSON</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> App <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
					initialize<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
					render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000066; font-weight: bold;">var</span> tweet <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
							avatar<span style="color: #339933;">:</span> <span style="color: #3366CC;">'avatar.jpg'</span><span style="color: #339933;">,</span>
							username<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Aaronius'</span><span style="color: #339933;">,</span>
							text<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Honey roasted peanuts rock my sox.'</span>
						<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
						<span style="color: #000066; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> TweetRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
							model<span style="color: #339933;">:</span> tweet
						<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
						<span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>row.$el<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
						<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> App<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>el<span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
		&lt;script type=&quot;text/template&quot; id=&quot;tweet-row-template&quot;&gt;
			&lt;div style=&quot;float: left&quot;&gt;&lt;img src=&quot;&lt;%= avatar %&gt;&quot;/&gt;&lt;/div&gt;
			&lt;div style=&quot;margin-left: 60px&quot;&gt;
				&lt;p&gt;&lt;%= username %&gt;&lt;/p&gt;
				&lt;p&gt;&lt;%= text %&gt;&lt;/p&gt;
			&lt;/div&gt;
		&lt;/script&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

<p>You&#8217;ll see in TweetRow we&#8217;ve created a <code>render()</code> method which populates the inner HTML of the view&#8217;s DOM element (in this case, a div that was automatically created by <code>Backbone.View</code>).  By default, <code>Backbone.View</code> already has a <code>render()</code> method but it doesn&#8217;t perform any operation.  Nothing in Backbone even calls it either.  Truthfully, the <code>render()</code> method is more of a convention than anything, but I highly suggest you follow it.  The <code>render()</code> method should do any work needed to update the view&#8217;s DOM element.  Keep in mind that optimally you should be able to call <code>render()</code> multiple times if needed and your view should still render and function properly.  Also, it&#8217;s recommended you <code>return this;</code> at the end to allow for <a href="http://css.dzone.com/news/javascript-chaining-your-metho" target="_blank">method chaining</a>.</p>
<p>There are some differences in the Backbone community regarding how <code>render()</code> should be called.  You&#8217;ll often see examples that show the parent view calling the <code>render()</code> method of a child view.  In our case, that would mean rather than calling <code>render()</code> from our <code>initialize()</code> method within the view we would call it later outside of the view before we append the element to a parent DOM element:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>code<span style="color: #339933;">&gt;</span><span style="color: #000066; font-weight: bold;">this</span>.$el.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>row.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.$el<span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;/</span>code<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>I prefer to only call <code>render()</code> from within the view itself&#8211;never from another view&#8211;even a parent view. It&#8217;s my opinion that views should not be concerned with when other views need to be rendered or re-rendered. Others may disagree and I reserve the right to join them someday. :)</p>
<h3>Model-View knowledge</h3>
<p>It may be tempting to store a view or two on a model. Steer clear of this. Views should know about models and be able to bind to their events but not the other way around.  This is standard MVC protocol and for good reason. Logic flow and interaction among application actors can easily become unwieldy when introducing views into models.</p>
<h3>Event delegation</h3>
<p>A helpful nugget Backbone views offer is event delegation.  Normally when dealing with DOM element interactions you would have to query for elements using jQuery and then bind to their events.  It&#8217;s not difficult, but Backbone provides a shortcut for doing so:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> DocumentView <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">View</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	events<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #3366CC;">&quot;dblclick&quot;</span>                <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;open&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">&quot;click .icon.doc&quot;</span>         <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;select&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #3366CC;">&quot;mouseover .title .date&quot;</span>  <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;showTooltip&quot;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	render<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		...
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	open<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		...
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	select<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		...
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
	showTooltip<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		...
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>As you can see, an <code>events</code> property is set. Each entry could be read as follows:</p>
<ul>
<li>When <code>this.el</code> is double-clicked, call the <code>open()</code> method.</li>
<li>When descendants of <code>this.el</code> matching the <code>.icon.doc</code> <a href="http://www.w3.org/TR/css3-selectors" target="_blank">CSS selector</a> are clicked, call the <code>select()</code> method.</li>
<li>When descendants of <code>this.el</code> matching the <code>.title .date</code> <a href="http://www.w3.org/TR/css3-selectors" target="_blank">CSS selector</a> are moused over, call the <code>showTooltip()</code> method.</li>
</ul>
<p>Another bonus about this shortcut is that referencing the <code>this</code> context from within the callback methods will still refer to the view&#8211;not the DOM element that triggered the event.  If you&#8217;ve used JavaScript for much time, you&#8217;ll know that handling the <code>this</code> context can be a pain.</p>
<p>This event delegation generally is handled for you transparently. However, if you ever replace this.el with a different DOM element, be sure to call <code>this.setElement(newEl)</code> instead of just <code>this.el = newEl</code>.  The setElement() function will properly remove the event delegation from the old element and add it to the new element.  It will also set up the <code>this.$el</code> variable for you. Hopefully that will save you from pulling your hair out sometime.</p>
<h3>Other functionality</h3>
<p>jQuery allows us to search for elements only within <code>this.el</code>:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> paragraphs <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">el</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>As a convenience, Backbone provides a shortcut to do the same thing:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> paragraphs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'p'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>With the appropriate usage of views we can build more maintainable, scalable apps.  I invite you to read more in the <a href="http://documentcloud.github.com/backbone/#View" target="_blank">Backbone.View documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-views/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Backbone.js Collections</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-collections/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-collections/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 05:10:32 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[collection]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[state]]></category>
		<category><![CDATA[underscore.js]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1215</guid>
		<description><![CDATA[Updated Aug 11, 2012 to reflect current library versions. Collections of items are amazingly pervasive in applications. Gmail deals with collections of emails. Twitter deals with collections of tweets. Facebook deals with collections of friends, updates, and apps. Very often these collections contain living data. The app may be constantly updating with new, changed, or [...]]]></description>
				<content:encoded><![CDATA[<p><b>Updated Aug 11, 2012 to reflect current library versions.</b></p>
<p>Collections of items are amazingly pervasive in applications. Gmail deals with collections of emails. Twitter deals with collections of tweets. Facebook deals with collections of friends, updates, and apps. Very often these collections contain living data. The app may be constantly updating with new, changed, or removed items from the server. Maybe users are able to filter, sort, add, edit, or delete items and maybe they can do so from multiple views that need to be synchronized.</p>
<p>Usually when we think of collections of items in software terms with think of an array.  Objects can be added and removed from an array easily enough but a native array on its own has no ability to broadcast notice of the change.  Why do we care?  Let&#8217;s say we&#8217;re building an RSS reader that shows the user a feed of articles from their subscriptions.  The articles come from an array we loaded from the server.  Each article contains a remove button next to it that allows the user to remove the article from the feed.  Let&#8217;s also say in the top-right corner of the screen, separate from the feed of articles, we have a little counter that shows the user how many articles they currently have remaining in the feed.  Assume that the feed has a JavaScript object managing it and the counter has a separate JavaScript object managing it.</p>
<p>When the user clicks a remove button to remove an article from the feed, it&#8217;s easy enough for us to remove the article from the feed itself and the accompanying array of articles, but how do we update the counter? The most direct approach is to give the feed view a reference to the counter view. That way the feed can just call a function on the counter view to tell it to refresh itself, right? Noooooooooo! Sure, it might function, but that&#8217;s a very good way to couple our views and reduce our flexibility. Our views would know more than necessary about each other. In this case, the data should drive the views instead of the views driving each other.  Unfortunately, it&#8217;s difficult for our data (the array of articles) to drive the view using a native array because the counter can&#8217;t &#8220;watch&#8221; the array for a removal of an article.  Native arrays do not broadcast events when items are added or removed.</p>
<p>You&#8217;ll notice a great similarity between what I&#8217;ve written above regarding native arrays resulting in view coupling and what I wrote in my previous post about <a href="/javascript/javascript-architecture-backbone-js-models/">native objects resulting in view coupling</a>.  Indeed, there are a lot of similarities and they are both resolved by <a href="/javascript/javascript-architecture-backbone-js-events/">implementing the observer pattern</a> within our data structures. Just as a <a href="/javascript/javascript-architecture-backbone-js-models/">native object can be wrapped by a Backbone model</a> in order to broadcast attribute changes, an array can be wrapped by a Backbone collection to broadcast additions and removals.<span id="more-1215"></span></p>
<h3>Eventful collections</h3>
<p>Collections trigger events when models are added or removed.  Let&#8217;s take a look at how this might look:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Create individual models.</span>
<span style="color: #000066; font-weight: bold;">var</span> taleOfTwoCities <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'A Tale of Two Cities'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Charles Dickens'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Chapman &amp; Hall'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> goodEarth <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'The Good Earth'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Pearl S. Buck'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'John Day'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Create collection, passing in A Tale of Two Cities that will make up</span>
<span style="color: #006600; font-style: italic;">// our initial collection.  Alternatively, we could have passed in nothing </span>
<span style="color: #006600; font-style: italic;">// and then called books.add(taleOfTwoCities) later.</span>
<span style="color: #000066; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Collection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>taleOfTwoCities<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Set up the handler for when a model is added.</span>
<span style="color: #000066; font-weight: bold;">var</span> onAdd <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>book<span style="color: #339933;">,</span> books<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Book '</span> <span style="color: #339933;">+</span> book.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' added at index '</span> <span style="color: #339933;">+</span> options.<span style="color: #660066;">at</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'. '</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'The collection now contains '</span> <span style="color: #339933;">+</span> books.<span style="color: #660066;">length</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' models.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Set up the handler for when a model is removed.</span>
<span style="color: #000066; font-weight: bold;">var</span> onRemove <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>book<span style="color: #339933;">,</span> books<span style="color: #339933;">,</span> options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Book '</span> <span style="color: #339933;">+</span> book.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' removed from index '</span> <span style="color: #339933;">+</span> options.<span style="color: #660066;">index</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Set up event listeners.</span>
books.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'add'</span><span style="color: #339933;">,</span> onAdd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
books.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'remove'</span><span style="color: #339933;">,</span> onRemove<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Add good earth and index 0 (before the Tale of Two Cities).</span>
books.<span style="color: #660066;">add</span><span style="color: #009900;">&#40;</span>goodEarth<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>at<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Remove both books.</span>
books.<span style="color: #660066;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>taleOfTwoCities<span style="color: #339933;">,</span> goodEarth<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// We could have removed just a single book like this:</span>
<span style="color: #006600; font-style: italic;">// books.remove(goodEarth);</span></pre></td></tr></table></div>

<p>I&#8217;ve added several comments inline, but let&#8217;s review what&#8217;s going on here.  When we add a model to the collection, we use the <code>add()</code> function.  Optionally, you can pass the index where you want the model to be added.  We specify 0 so <code>goodEarth</code> will be placed at the start of the collection.  By default, it will be added at the end. When we add the model, the <code>add</code> event is automatically triggered by the collection and any respective handlers are called.  In our case, the <code>onAdd</code> function is called.  The three arguments are:</p>
<ol>
<li>The added model.</li>
<li>The collection to which the model was added.</li>
<li>Any options used to add the model.</li>
</ol>
<p>You can add one or more models at a time.</p>
<p>We then removed both our book models at the same time.  Even though we remove them using a single <code>remove()</code> call, the <code>onRemove</code> handler is called twice&#8211;once for each model being removed.  The three arguments are:</p>
<ol>
<li>The removed model.</li>
<li>The collection from which the model was removed.</li>
<li>Any options used to remove the model.</li>
</ol>
<p>You can remove one or more models at a time.  Notice that even though we didn&#8217;t explicitly pass any options object as a second parameter to <code>remove()</code>, the <code>options</code> argument coming into <code>onRemove</code> does exist and is populated with the index at which the model resided.</p>
<p>The above code produces the following alerts, in order:</p>
<ol>
<li>Book The Good Earth added at index 0. The collection now contains 2 models.</li>
<li>Book A Tale of Two Cities removed from index 1.</li>
<li>Book The Good Earth removed from index 0.</li>
</ol>
<p>What if you wanted to know when the title of any model in the collection changes?  Looping through all the models and adding an event listener to each one is a pain, especially when we have to remember to always add event listeners to models being added and remove event listeners from models being removed. Fortunately, Backbone collections <a href="http://en.wikipedia.org/wiki/Bucket_brigade" target="_blank">bucket-brigade</a> events coming from the models themselves which can be very handy.  Let&#8217;s see how this works:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> taleOfTwoCities <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'A Tale of Two Cities'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Charles Dickens'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Chapman &amp; Hall'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> goodEarth <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'The Good Earth'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Pearl S. Buck'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'John Day'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Collection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span>taleOfTwoCities<span style="color: #339933;">,</span> goodEarth<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> onTitleChange <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>book<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	alert<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Book title changed from '</span> <span style="color: #339933;">+</span> book.<span style="color: #660066;">previousAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">title</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' to '</span> <span style="color: #339933;">+</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
books.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'change:title'</span><span style="color: #339933;">,</span> onTitleChange<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
goodEarth.<span style="color: #000066; font-weight: bold;">set</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Good Earth, The'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Notice we didn&#8217;t add an event listener for <code>change:title</code> on each individual book model, but only on the collection containing the book models.  I even threw a little bonus nugget in there to show how we can retrieve the previous title.</p>
<h3>Model configuration</h3>
<p>So far we&#8217;ve been instantiating our own Backbone models before adding them to a collection.  However, we can configure our collection to use a certain model class.  We can then just pass a native object to the collection.  Under the hood, the collection will then instantiate the configured model class for us and pass our native object into its constructor:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> Book <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Model</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	defaults<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'historical'</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> BookCollection <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Collection</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	model<span style="color: #339933;">:</span> Book
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> BookCollection<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
books.<span style="color: #660066;">add</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'A Tale of Two Cities'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Charles Dickens'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Chapman &amp; Hall'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
books.<span style="color: #660066;">add</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'The Good Earth'</span><span style="color: #339933;">,</span>
	author<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Pearl S. Buck'</span><span style="color: #339933;">,</span>
	publisher<span style="color: #339933;">:</span> <span style="color: #3366CC;">'John Day'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Notice in this case we actually extended <code>Backbone.Collection</code> and set the model property.  Another option is to just set the model property on a newly instantiated collection:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Collection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
books.<span style="color: #660066;">model</span> <span style="color: #339933;">=</span> Book<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If you don&#8217;t configure the model class, <code>Backbone.Collection</code> uses <code>Backbone.Model</code> by default.  Configuring a collection with a model class may not seem very beneficial at the moment, but hopefully it will make more sense when talking about loading data into a collection.</p>
<h3>Persistence</h3>
<p><a href="/javascript/javascript-architecture-backbone-js-models/">Similar to Backbone models</a>, collections also have the ability to fetch data from persistence.  Let&#8217;s see how this works:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> Book <span style="color: #339933;">=</span> Backbone.<span style="color: #660066;">Model</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	defaults<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
		genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'historical'</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> onSuccess <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>books<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">var</span> firstBook <span style="color: #339933;">=</span> books.<span style="color: #660066;">at</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	alert<span style="color: #009900;">&#40;</span>firstBook.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' is of genre '</span> <span style="color: #339933;">+</span> firstBook.<span style="color: #000066; font-weight: bold;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'genre'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Collection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
books.<span style="color: #660066;">model</span> <span style="color: #339933;">=</span> Book<span style="color: #339933;">;</span>
books.<span style="color: #660066;">url</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/books.php'</span><span style="color: #339933;">;</span>
books.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	success<span style="color: #339933;">:</span> onSuccess
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Like our previous example, we&#8217;ve configured a collection to use the <code>Book</code> model class.  We&#8217;ve also configured an endpoint url of <code>/books.php</code>.  When we call <code>fetch()</code>, the collection will issue a <code>GET</code> request to the endpoint.  In my case, I&#8217;ve set up the endpoint to return a JSON array of books.  Once the JSON is returned, the collection will loop through the array, instantiating and populating a model  (in our case, a <code>Book</code> model) for each item.  Then, the model will be added to the collection itself.</p>
<p>The example above will alert <code>A Tale of Two Cities is of genre historical</code>.  The interesting part here is the genre was never sent from the server.  Instead, the model picked up the default genre, historical, because we extended <code>Backbone.Model</code> to create our <code>Book</code> class and set the default genre there.  Hopefully you can now see the benefit of configuring collections to use a specific model class.</p>
<h3>Additional functionality</h3>
<p>We&#8217;ve only covered a subset of the functionality of Backbone collections.  Beyond what we&#8217;ve discussed, collections can be <a href="http://documentcloud.github.com/backbone/#Collection-comparator" target="_blank">sorted</a> and <a href="http://documentcloud.github.com/backbone/#Collection-reset" target="_blank">reset</a>. Models can be <a href="http://documentcloud.github.com/backbone/#Collection-get" target="_blank">retrieved by id</a>.  Models can be <a href="http://documentcloud.github.com/backbone/#Collection-create" target="_blank">both saved to the server and added to the collection in one method call</a>.</p>
<p>Collections can also be configured, for example, to <a href="http://documentcloud.github.com/backbone/#Sync" target="_blank">load</a> and <a href="http://documentcloud.github.com/backbone/#Collection-parse" target="_blank">parse</a> data in a specific manner.</p>
<p>Beyond that, all collections have a bucketload of underscore functions baked in.  In <a href="/javascript/javascript-architecture-underscore-js/">JavaScript Architecture: Underscore.js</a>, I showed an example of how we can get an array of usernames from an array of user objects using the <a href="http://documentcloud.github.com/underscore/" target="_blank">Underscore</a> <a href="http://documentcloud.github.com/underscore/#pluck" target="_blank">pluck()</a> function:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> usernames <span style="color: #339933;">=</span> _.<span style="color: #660066;">pluck</span><span style="color: #009900;">&#40;</span>users<span style="color: #339933;">,</span> <span style="color: #3366CC;">'username'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Since collections have Underscore functions baked in, we can likewise get an array of all titles of the books in the collection in an even more concise manner:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">var</span> titles <span style="color: #339933;">=</span> books.<span style="color: #660066;">pluck</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Nice! There are <a href="http://documentcloud.github.com/backbone/#Collection-Underscore-Methods" target="_blank">many other Underscore functions</a> baked into collections you should check out as well.  These will make your life easier and trim down your code.</p>
<p>Read more in the <a href="http://documentcloud.github.com/backbone/#Collection" target="_blank">Backbone.Collection</a> documentation.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-collections/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
	</channel>
</rss>
