<?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://unfoldingneurons.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>Thu, 12 Jan 2012 17:51:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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[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 tool that can be used to solve problems common [...]]]></description>
			<content:encoded><![CDATA[<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:</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>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>
<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>
</ul>
<p>What&#8217;s so special about these properties?  Let&#8217;s take a look:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066;">alert</span><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: #660066;">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;
		<span style="color: #000066;">alert</span><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;
		<span style="color: #000066;">alert</span><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: #003366; font-weight: bold;">var</span> tweet <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #003366; 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></div></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"><div 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: #003366; 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: #003366; 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: #003366; 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: #003366; 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;">&#40;</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: #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: #003366; 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: #003366; 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: #003366; 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: #003366; font-weight: bold;">var</span> tweet <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> row <span style="color: #339933;">=</span> <span style="color: #003366; 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>.<span style="color: #660066;">el</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>row.<span style="color: #660066;">el</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: #003366; font-weight: bold;">var</span> app <span style="color: #339933;">=</span> <span style="color: #003366; 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></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>code<span style="color: #339933;">&gt;</span>this.<span style="color: #660066;">el</span>.<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>.<span style="color: #660066;">el</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;&lt;/</span>code<span style="color: #339933;">&gt;</span></pre></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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: #003366; 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;
	<span style="color: #000066;">open</span><span style="color: #339933;">:</span> <span style="color: #003366; 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: #003366; 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: #003366; 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></div></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>It&#8217;s important to understand a little about how this event delegation is set up under the hood.  the constructor of <code>Backbone.View</code> looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">Backbone.<span style="color: #660066;">View</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>options<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;">cid</span> <span style="color: #339933;">=</span> _.<span style="color: #660066;">uniqueId</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'view'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._configure<span style="color: #009900;">&#40;</span>options <span style="color: #339933;">||</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>._ensureElement<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">delegateEvents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initialize</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Starting with the third operation (<code>this._ensureElement();</code>), the view ensures that either <code>el</code> was passed in and, if not, will create an <code>el</code> on our behalf as described previously.  It then calls <code>this.delegateEvents()</code> <i>before</i> calling <code>this.initialize()</code>. The <code>this.delegateEvents()</code> method is what sets up the event bindings as dictated in our <code>events</code> property.  It sets up these bindings on whatever is currently <code>this.el</code>.  This means if you overwrite <code>this.el</code> from within <code>initialize()</code>, you&#8217;ll need to manually call <code>this.delegateEvents()</code> afterward to set up the event bindings using the new <code>this.el</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">initialize<span style="color: #339933;">:</span> <span style="color: #003366; 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;">el</span> <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;div&gt;Overriding this.el&lt;/div&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">delegateEvents</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</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></pre></div></div>

<p>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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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></div></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>3</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[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 [...]]]></description>
			<content:encoded><![CDATA[<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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Create individual models.</span>
<span style="color: #003366; font-weight: bold;">var</span> taleOfTwoCities <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> goodEarth <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> onAdd <span style="color: #339933;">=</span> <span style="color: #003366; 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>
	<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Book '</span> <span style="color: #339933;">+</span> book.<span style="color: #660066;">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: #003366; font-weight: bold;">var</span> onRemove <span style="color: #339933;">=</span> <span style="color: #003366; 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>
	<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'Book '</span> <span style="color: #339933;">+</span> book.<span style="color: #660066;">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 bindings.</span>
books.<span style="color: #660066;">bind</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;">bind</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></div></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 binding to each one is a pain, especially when we have to remember to bind to models being added and unbind 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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> taleOfTwoCities <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> goodEarth <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; font-weight: bold;">var</span> onTitleChange <span style="color: #339933;">=</span> <span style="color: #003366; 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>
	<span style="color: #000066;">alert</span><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;">bind</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: #660066;">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></div></div>

<p>Notice we didn&#8217;t bind to <code>change:title</code> on each individual book model, but 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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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: #003366; 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: #003366; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #003366; 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></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #003366; 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></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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: #003366; font-weight: bold;">var</span> onSuccess <span style="color: #339933;">=</span> <span style="color: #003366; 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: #003366; 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>
	<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>firstBook.<span style="color: #660066;">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: #660066;">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: #003366; font-weight: bold;">var</span> books <span style="color: #339933;">=</span> <span style="color: #003366; 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></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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></div></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"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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></div></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>1</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Backbone.js Models</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-models/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-models/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 21:41:42 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[state]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1173</guid>
		<description><![CDATA[Models contain the data or state of an application. Examples of a model would be a book, car, or customer. A book model would contain typical attributes of a book: title, author, genre, and publisher. A regular JavaScript object could contain this data like so: var book = &#123; title: 'A Tale of Two Cities', [...]]]></description>
			<content:encoded><![CDATA[<p>Models contain the data or state of an application.  Examples of a model would be a book, car, or customer.  A book model would contain typical attributes of a book: title, author, genre, and publisher.  A regular JavaScript object could contain this data like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> book <span style="color: #339933;">=</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>
	genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'historical'</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: #339933;">;</span></pre></div></div>

<p>But this will soon present a problem.  For illustration purposes let&#8217;s say you have view A that shows the book information and a separate view B where the user can change the book information.  When the information is changed from view B, view A needs to know about it so it can update to show the new info to the user.  Because our regular JavaScript object doesn&#8217;t have any way to notify view A of the change, view B would need a reference to view A so view B can call a method on view A telling it that the book object has been updated. Better yet, maybe we give view B <a href="/javascript/javascript-architecture-backbone-js-events/" target="_blank">event triggering powers</a> and view A could just bind to view B&#8217;s events. Either way, these options should be frantically waiving red flags in your skull. Your views would now have to be aware of each other in at least one direction and that&#8217;s one direction too many.  We want to free our views from the necessity of being aware of each other.<span id="more-1173"></span></p>
<h3>Eventful models</h3>
<p>Backbone&#8217;s models take advantage of the <a href="/javascript/javascript-architecture-backbone-js-events/">Backbone.Events observer pattern implementation</a> so we can deal with this appropriately:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> book <span style="color: #339933;">=</span> <span style="color: #003366; 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>
	genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'historical'</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;
book.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'change:genre'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>model<span style="color: #339933;">,</span> genre<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #006600; font-style: italic;">// Method 1: Use arguments.</span>
	<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'genre for '</span> <span style="color: #339933;">+</span> model.<span style="color: #660066;">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;">' changed to '</span> <span style="color: #339933;">+</span> genre<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #006600; font-style: italic;">// Method 2: Use book variable captured in closure.</span>
	<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'genre for '</span> <span style="color: #339933;">+</span> book.<span style="color: #660066;">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;">' changed to '</span> <span style="color: #339933;">+</span> book.<span style="color: #660066;">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: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
book.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>genre<span style="color: #339933;">:</span> <span style="color: #3366CC;">'social criticism'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>When we instantiate a Backbone model and pass in the native object containing our book information, the model then wraps these attributes.  Attributes can then be retrieved and stored using the <code>get</code> and <code>set</code> methods.  You can set brand new attributes, <a href="http://documentcloud.github.com/backbone/#Model-unset" target="_blank">unset</a> old ones, or <a href="http://documentcloud.github.com/backbone/#Model-clear" target="_blank">clear them all</a> if you feel the need.  If you try to access the attributes directly (e.g., <code>alert(book.genre);</code>) you&#8217;ll get an error.  The <code>get</code> and <code>set</code> methods are required to deal with a JavaScript limitation in order to trigger events when attributes are changed.</p>
<p>By using a Backbone model our views can now watch the book directly for when the genre changes. Notice that Backbone automatically took the name of the attribute we changed, <code>genre</code>, prepended it with <code>change:</code>, then triggered an event using the resulting string as the key.  By watching for the <code>change:genre</code> event, we can be notified any time the genre attribute is changed.</p>
<p>We can also extend Backbone.Model and set defaults using the <code>defaults</code> hash:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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: #003366; font-weight: bold;">var</span> taleOfTwoCities <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Book<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: #003366; font-weight: bold;">var</span> goodEarth <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Book<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;">// Alerts &quot;A Tale of Two Cities: historical&quot;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>taleOfTwoCities.<span style="color: #660066;">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;">': '</span> <span style="color: #339933;">+</span> taleOfTwoCities.<span style="color: #660066;">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>
&nbsp;
<span style="color: #006600; font-style: italic;">// Alerts &quot;The Good Earth: historical&quot;</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>goodEarth.<span style="color: #660066;">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;">': '</span> <span style="color: #339933;">+</span> goodEarth.<span style="color: #660066;">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></pre></div></div>

<p>Now every book that is instantiated will receive the &#8220;historical&#8221; genre by default which, of course, can be overridden.</p>
<h3>Persistence using a static URL</h3>
<p>How do we get data to and from a remote server? Glad you asked. Models have syncing functionality built-in. You don&#8217;t have to use it, but it can be really nice.  Here&#8217;s the simplest form:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> book <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Backbone.<span style="color: #660066;">Model</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
book.<span style="color: #660066;">url</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/book.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> fetchSuccess <span style="color: #339933;">=</span> <span style="color: #003366; 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;">alert</span><span style="color: #009900;">&#40;</span>book.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</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;
book.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>success<span style="color: #339933;">:</span> fetchSuccess<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In this case, there&#8217;s no technical need to even extend <code>Backbone.Model</code>.  We just instantiate it, set our endpoint url, and call <code>fetch()</code>.  As long as the endpoint returns <a href="http://www.json.org/" target="_blank">JSON</a> for a single book, the JSON properties will be merged into our model.  The result is a model object that then behaves just as any other Backbone model would.  Note that we passed a callback function to <code>fetch()</code> that will be executed after a successful response.  We could have also <a href="http://documentcloud.github.com/backbone/#Model-fetch" target="_blank">passed an error callback function</a> to handle any issues encountered while communicating with the server.</p>
<p>As far as saving data, here&#8217;s how we can save a new book to the server:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> book <span style="color: #339933;">=</span> <span style="color: #003366; 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 Tragedy of the Commons'</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;">// Or we could've done this instead of passing it into the constructor:</span>
<span style="color: #006600; font-style: italic;">// book.set({title: 'The Tragedy of the Commons'});</span>
&nbsp;
book.<span style="color: #660066;">url</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'/book.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> saveSuccess <span style="color: #339933;">=</span> <span style="color: #003366; 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;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'book saved!'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
book.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>success<span style="color: #339933;">:</span> saveSuccess<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In this case, the <code><a href="http://documentcloud.github.com/backbone/#Model-save" target="_blank">save()</a></code> method will send a POST request to the server containing the book data in JSON format.  If the model already exists on the server (which by default is deemed true if the model contains an <code>id</code> attribute), the <code>save()</code> method will send a PUT request instead of a POST. The <code><a href="http://documentcloud.github.com/backbone/#Model-destroy" target="_blank">destroy()</a></code> method will issue a DELETE request.</p>
<h3>Persistence using a pattern URL</h3>
<p>While a static url may do in some cases (previously <code>/book.php</code>), it&#8217;s more likely you&#8217;ll have a url pattern for retrieving your models.  For example, to get the book with ID = 2 your endpoint may be <code>http://example.com/books/2</code>.  The &#8220;books&#8221; part of the path is common for all books, but the id on the end varies.  In this case we could do this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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>
	urlRoot<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/books'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> myBook <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Book<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>id<span style="color: #339933;">:</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> fetchSuccess <span style="color: #339933;">=</span> <span style="color: #003366; 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;">alert</span><span style="color: #009900;">&#40;</span>myBook.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</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: #006600; font-style: italic;">// alerts 'using url: /books/2'</span>
<span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'using url: '</span> <span style="color: #339933;">+</span> myBook.<span style="color: #660066;">url</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
myBook.<span style="color: #660066;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>success<span style="color: #339933;">:</span> fetchSuccess<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>By creating a Book class and setting the <code>urlRoot</code> property, we can instantiate a book, set the id property, and call <code>fetch()</code>.  By default a url will be composed with the pattern we&#8217;re looking for: <code>[urlRoot]/[id]</code>.  You can modify this pattern to suit your particular needs.  For example, we could set our model up to have a <code>[urlRoot]?id=[id]</code> pattern.  We do this by overriding the <code>url</code> property:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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>
	urlRoot<span style="color: #339933;">:</span> <span style="color: #3366CC;">'/books'</span><span style="color: #339933;">,</span>
	url<span style="color: #339933;">:</span> <span style="color: #003366; 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;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">urlRoot</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'?id='</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</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></pre></div></div>

<p>Notice in our examples <code>url</code> can be either a property or a method.</p>
<p>Even more likely than dealing with a single book here and there is the need to load and manage a list of books.  Fortunately, Backbone helps us there too and we&#8217;ll discuss this in the next post in the series. </p>
<h3>View state</h3>
<p>So far we&#8217;ve talked about models in the context of representing entities.  In our case, our entity is a book.  However, models can also come in handy for storing view state.</p>
<p>Take an application like Photoshop, Illustrator, Lightroom, or pretty much any IDE where there are numerous panels that can be shown or hidden.  For illustration purposes, let&#8217;s say we&#8217;re building a similar app and our requirements are that we have two panels.  Panel A happens to show a particular icon on it if and only if panel B is visible.  How do we notify panel A when panel B&#8217;s visibility is toggled?  Suffice it to say we also have a JavaScript object managing each of these panels (one per panel).</p>
<p>If we take the most direct approach, we could pass panel A&#8217;s JavaScript object to panel B and when panel B&#8217;s visibility is toggled (maybe there&#8217;s some sort of hide button within the panel itself) it calls a method on panel A.  Or we could just pass a function of panel A&#8217;s into panel B. Either way, that just smells bad.  Again, we&#8217;ve coupled our views.  This becomes increasingly problematic as we add more and more panels that need to be aware of each others&#8217; visibility.  Maybe due to UXD insanity the requirement changes such that 10 panels have to know about each others&#8217; visibility for one reason or another.  And then maybe we have a menu that shows a checkbox next to each of the names of the panels that are visible.  And then for memory management purposes we decide to completely destroy and create the panels&#8217; DOM elements and managing JavaScript objects altogether rather than just toggling visibility.  Now we have this massive web of object references amongst all the various panels and when we see these new requirements an hour before launch we start to panic.  You know this happens in the real world.</p>
<p>Unfortunately, we took the most direct, simple approach <em>now</em> for a lack of flexibility <em>later</em>.  This might work in the short term, but it adds to <a href="http://blog.effectiveui.com/?p=4591" target="_blank">technical debt</a> that may become overwhelming later on.</p>
<p>Instead, what if we created a model to store the state of the view.  Maybe we call it our <code>panelState</code> model and the attributes we store on the model might be <code>presetsVisible</code>, <code>histogramVisible</code>, and so on.  We can then share this model with any of the panels, the menu, or anything else that might need to know about their state.  We can also completely destroy a panel&#8217;s DOM element and managing JavaScript object when it&#8217;s hidden and we&#8217;re okay because rather than every panel having a reference to every other panel, they just have a reference to a single view state model that always exists.</p>
<h3>Additional functionality</h3>
<p>Additional functionality exists in models including <a href="http://documentcloud.github.com/backbone/#Model-validate" target="_blank">validating</a>, <a href="http://documentcloud.github.com/backbone/#Model-toJSON" target="_blank">extracting a native object from the <code>Backbone.Model</code> wrapper</a>, <a href="http://documentcloud.github.com/backbone/#Model-changedAttributes" target="_blank">determining which attributes have changed</a>, and more.</p>
<h3>Optionality and customization</h3>
<p>Just because Backbone gives you the ability to do all the things we&#8217;ve talked about, rest assured you&#8217;re not forced to use any of it.  It stays out of the way as much as you want.  If you choose, you can write your own function for loading your data wherever you want.  You can opt out of using Backbone models completely.  Likewise, if there&#8217;s functionality that doesn&#8217;t fit your system requirements, there are ways to customize the various aspects.  I&#8217;ll leave that for you as homework whenever you need it, but these are good research techniques to get you headed in the right direction: </p>
<ul>
<li>Read the <a href="http://documentcloud.github.com/backbone/" target="_blank">documentation</a></li>
<li><a href="http://lmgtfy.com/?q=how+do+I+codez+with+backbone.js" target="_blank">Google it</a></li>
<li>Search <a href="http://stackoverflow.com/" target="_blank">StackOverflow</a></li>
<li>Post question on <a href="http://stackoverflow.com/" target="_blank">StackOverflow</a></li>
<li>Ask the <a href="https://groups.google.com/group/backbonejs" target="_blank">Backbone Google group</a></li>
<li>Read the <a href="http://documentcloud.github.com/backbone/docs/backbone.html" target="_blank">annotated source</a></li>
</ul>
<p>Read more in the <a href="http://documentcloud.github.com/backbone/#Model" target="_blank">Backbone.Model documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-models/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Backbone.js Events</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-events/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-events/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 21:40:14 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[observer pattern]]></category>
		<category><![CDATA[publisher]]></category>
		<category><![CDATA[subscriber]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1161</guid>
		<description><![CDATA[Backbone.js is an MVC framework for JavaScript applications (although some legitimately argue it&#8217;s not technically MVC). Its purpose is to provide structure to your application so it can be modular, decoupled, and scalable. If you&#8217;re not sure why you may need an application framework, please read JavaScript Architecture: The Basics first. Backbone is not a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://documentcloud.github.com/backbone" target="_blank">Backbone.js</a> is an MVC framework for JavaScript applications (although <a href="http://lostechies.com/derickbailey/2011/12/23/backbone-js-is-not-an-mvc-framework/" target="_blank">some legitimately argue</a> it&#8217;s not technically MVC).  Its purpose is to provide structure to your application so it can be modular, decoupled, and scalable.  If you&#8217;re not sure why you may need an application framework, please read <a href="/javascript/javascript-architecture-the-basics/">JavaScript Architecture: The Basics</a> first.  Backbone is not a <a href="/javascript/javascript-architecture-jquery/">dom manipulation utility</a>,  <a href="/javascript/javascript-architecture-underscore-js/">templating engine</a>, or <a href="http://jqueryui.com/" target="_blank">UI component library</a>.</p>
<p>Backbone.js files and documentation can be found <a href="http://documentcloud.github.com/backbone/" target="_blank">here</a> or you can <a href="https://github.com/documentcloud/backbone/" target="_blank">get involved with the source and community at GitHub</a>.  At the time of this writing, the unminified, documented code is only about 1,200 lines long so don&#8217;t be afraid to dig in and walk through the code itself.  Heck, there&#8217;s even an <a href="http://documentcloud.github.com/backbone/docs/backbone.html" target="_blank">annotated version</a>.</p>
<h3>Backbone.Events</h3>
<p>At the heart of every <a href="http://en.wikipedia.org/wiki/Rich_Internet_application" target="_blank">RIA</a> is the <a href="http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript" target="_blank">observer pattern</a> (otherwise known as the publisher/subscriber pattern).  The observer pattern is a design pattern that allows an object to be notified when another object has something to say, or in other words, has an event which it wishes to broadcast.</p>
<p>DOM elements (links, buttons, containers, etc.) already have the observer pattern natively baked in which is why you can watch for when a button is clicked without using libraries like Backbone or jQuery.  However, there are times where we want our own JavaScript objects to trigger/dispatch events and we would normally have to write the implementation of this pattern ourselves.  That&#8217;s where Backbone comes in.  Backbone has this code for you in Backbone.Events.<span id="more-1161"></span></p>
<p>Backbone.Events provides an implementation of a string-key-based observer pattern.  In pseudo-code, it operates as follows. I&#8217;ve been changing a lot of poop-holes lately so let&#8217;s say I&#8217;m coding in object dad and object dad needs to know when object baby drops a turd in its deuce-trap:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> changeDeuceTrap <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	baby.<span style="color: #660066;">deuces</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
	baby.<span style="color: #660066;">shutCakeHole</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;
baby.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'turdDropped'</span><span style="color: #339933;">,</span> changeDeuceTrap<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>And somewhere within baby we have:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">trigger</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'turdDropped'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dad&#8217;s telling baby, &#8220;Let me know you dropped a turd so I can change your deuce-trap.&#8221;  If mom had access to the same baby, she could likewise watch for when the baby drops a turd and change the deuce-trap too.  If she does so, when the baby drops its next turd we&#8217;ll both the notified. In other words, multiple observers can watch for the same event.</p>
<p>You might think this is magic but it&#8217;s not.  What&#8217;s happening here is dad is literally passing the <code>changeDeuceTrap</code> function to baby.  Baby then maintains an array for <code>turdDropped</code> and adds <code>changeDeuceTrap</code> to the array.  If another observer chooses to listen for the same event, that observer&#8217;s function will also be added to the same array inside baby.  When baby drops a turd, it iterates through the array calling all the &#8220;callback&#8221; functions it contains.</p>
<p>While we can easily <a href="http://documentcloud.github.com/backbone/#Events" target="_blank">give any object event-triggering powers using Backbone.Events</a>, don&#8217;t worry about it for now. Backbone.Model and Backbone.Collection already have Backbone.Events baked in and those are the main types of objects triggering events in our applications.</p>
<p>I should mention <a href="http://api.jquery.com/trigger/" target="_blank">jQuery has an observer pattern implementation of its own</a> but we&#8217;ll be focusing on Backbone.</p>
<p>Read more in the <a href="http://documentcloud.github.com/backbone/#Events" target="_blank">Backbone.Events documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-backbone-js-events/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>Speaking on JavaScript at 360&#124;Flex 2012</title>
		<link>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/</link>
		<comments>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 05:14:19 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[360|Flex]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[speaker]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1154</guid>
		<description><![CDATA[It&#8217;s almost time for another 360&#124;Flex conference! This conference will be held in Denver, Colorado, April 15-18, 2012. Get your tickets fast while discounts are available! It&#8217;s always a huge opportunity to learn new things and get in touch and have fun with the community. I&#8217;ve accepted the honor of speaking at this year&#8217;s conference [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost time for another <a href="http://www.360flex.com/" target="_blank">360|Flex</a> conference! This conference will be held in Denver, Colorado, April 15-18, 2012.  Get your tickets fast while discounts are available! It&#8217;s always a huge opportunity to learn new things and get in touch and have fun with the community.</p>
<p>I&#8217;ve accepted the honor of speaking at this year&#8217;s conference and will be speaking on JavaScript on Wednesday at 10:50am.  As you probably know, the Adobe community has really been shaken up over the last few months.  Adobe&#8217;s position on Flash and Flex has morphed and many engineers are taking a closer look at other technologies.  While JavaScript holds a stigma of being a red-headed step-child from the same orphanage as ActionScript 1, many see it as the inevitable future of the web.  While the language hasn&#8217;t evolved much, libraries and patterns have shaped up to help provide an environment conducive to building robust, dynamic enterprise apps.  We&#8217;ll discuss these libraries and patterns, learn how they relate to Flex, and make a comfortable home away from home.</p>
<p>Many of the concepts will be pulled from the <a href="/javascript/javascript-architecture-the-basics/" target="_blank">JavaScript architecture series</a> I recently started. Also, while I am a software engineer at Adobe, my thoughts are my own and do not represent those of Adobe.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/flex/speaking-on-javascript-at-360flex-2012/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JavaScript Architecture: Underscore.js</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-underscore-js/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-underscore-js/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 06:18:18 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[backbone.js]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[underscore.js]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1103</guid>
		<description><![CDATA[Underscore.js, like jQuery, is a toolbox of utilities. Check out the website for a list of functionality it provides, but I&#8217;ll split it into two parts: Array/Object/Function manipulation As we create software is seems like we come in contact with the same patterns over and over. Usually, we end up re-writing them over and over [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://documentcloud.github.com/underscore/" target="_blank">Underscore.js</a>, like <a href="/javascript/javascript-architecture-jquery/" target="_blank">jQuery</a>, is a toolbox of utilities.  Check out the website for a list of functionality it provides, but I&#8217;ll split it into two parts:</p>
<h3>Array/Object/Function manipulation</h3>
<p>As we create software is seems like we come in contact with the same patterns over and over.  Usually, we end up re-writing them over and over as well.  Take an array of user objects, each with a <code>username</code> property.  We need an array of all the usernames from all the objects.  So, like many times before, we create a new array to populate, create a for loop, snag the object at the current index, grab the username and push it into the array.</p>
<p>To me, that&#8217;s boring.  It&#8217;s mundane.  Underscore makes it fun again.  With Underscore, we just use <a href="http://documentcloud.github.com/underscore/#pluck" target="_blank">pluck()</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; 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></div></div>

<p>Ah&#8230;concise, fast, and boilerplate is gone.  Want to find all objects within an array that pass a specific test?  Use the <code><a href="http://documentcloud.github.com/underscore/#filter" target="_blank">filter()</a></code> function.  Just want a reference to the first one that passes the test? Use the <code><a href="http://documentcloud.github.com/underscore/#find" target="_blank">find()</a></code> function.  Want to retrieve the union of two arrays, that is, retrieve a single array of all unique objects contained within multiple other arrays?  Try the <code><a href="http://documentcloud.github.com/underscore/#union" target="_blank">union()</a></code> function.  Merge properties of multiple objects into a single object?  Use <code><a href="http://documentcloud.github.com/underscore/#extend" target="_blank">extend()</a></code>.</p>
<p>Once you grasp the power of Underscore you&#8217;ll find yourself being more productive with less code while having more fun.  Some have called it the bowtie for jQuery&#8217;s tux.  I concur.<span id="more-1103"></span></p>
<h3>Templating</h3>
<p>The <a href="http://documentcloud.github.com/underscore/#template" target="_blank">template()</a> function is only one of the many listed for Underscore, but its purpose is <em>very</em> important.</p>
<p>Let&#8217;s say you&#8217;re building an app to manage your todo items.  When the user creates a todo, it&#8217;s your job to create a todo row for the view.  And maybe you want to allow them to select the row using a checkbox, delete the row, or edit the row in-line.  Without using a templating engine, you might end up with something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> todoTemplate <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span> <span style="color: #339933;">+</span>
	<span style="color: #3366CC;">'&lt;div class=&quot;todo '</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>done <span style="color: #339933;">?</span> <span style="color: #3366CC;">'done'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&quot;&gt;'</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'&lt;div class=&quot;display&quot;&gt;'</span> <span style="color: #339933;">+</span>
			<span style="color: #3366CC;">'&lt;input class=&quot;check&quot; type=&quot;checkbox&quot; '</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>done <span style="color: #339933;">?</span> <span style="color: #3366CC;">'checked=&quot;checked&quot;'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' /&gt;'</span> <span style="color: #339933;">+</span>
			<span style="color: #3366CC;">'&lt;div class=&quot;todo-text&quot;&gt;&lt;/div&gt;'</span> <span style="color: #339933;">+</span>
			<span style="color: #3366CC;">'&lt;span class=&quot;todo-destroy&quot;&gt;&lt;/span&gt;'</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'&lt;/div&gt;'</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'&lt;div class=&quot;edit&quot;&gt;'</span> <span style="color: #339933;">+</span>
			<span style="color: #3366CC;">'&lt;input class=&quot;todo-input&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;'</span> <span style="color: #339933;">+</span>
		<span style="color: #3366CC;">'&lt;/div&gt;'</span> <span style="color: #339933;">+</span>
	<span style="color: #3366CC;">'&lt;/div&gt;'</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is troublesome.  First, your html is likely buried somewhere inside your JavaScript code. This makes re-skinning an app much harder since you now have to track down all your html strings scattered throughout your logic.  Second, concatenation takes time, is risky, and falls under the categories of mundane and frustrating. You have to deal with escaping and indentation. Your IDE probably isn&#8217;t going to color-code, code-hint, or auto-indent as well as it could if it were plain html. It&#8217;s easy to make a mistake and, since JavaScript is loosely typed, you might not find these mistakes until runtime. Also, if you dish your code off to HTML/CSS gurus, they now have to deal with these problems too.
</ul>
<p>Templating engines provide a better way of managing the situation.  What if we added this at the bottom of our <code>body</code> tag instead:</p>

<div class="wp_syntax"><div class="code"><pre class="html4stric" style="font-family:monospace;">&lt;script type=&quot;text/template&quot; id=&quot;item-template&quot;&gt;
	&lt;div class=&quot;todo &lt;%= done ? 'done' : '' %&gt;&quot;&gt;
		&lt;div class=&quot;display&quot;&gt;
			&lt;input class=&quot;check&quot; type=&quot;checkbox&quot; &lt;%= done ? 'checked=&quot;checked&quot;' : '' %&gt; /&gt;
			&lt;div class=&quot;todo-text&quot;&gt;&lt;/div&gt;
			&lt;span class=&quot;todo-destroy&quot;&gt;&lt;/span&gt;
		&lt;/div&gt;
		&lt;div class=&quot;edit&quot;&gt;
			&lt;input class=&quot;todo-input&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/script&gt;</pre></div></div>

<p>There are a few things to note here.  </p>
<ul>
<li>The code is plain HTML except for those things that can be dynamic which are inline (<code><%=...%></code>).</li>
<li>The dynamic portions reference a variable called <code>done</code>.  We&#8217;ll talk about that in a minute.</li>
<li>The code is wrapped in a script tag with a type of <code>text/template</code> meaning it won&#8217;t be interpreted as JavaScript (the default script type) by the browser.  If it were, the browser would throw errors.</li>
<li>The script tag has an ID which allows us to later access its content.</li>
</ul>
<p>At this point, the code inside the <code>script</code> tag is just innate text.  The browser won&#8217;t try to execute it or anything of that nature.  That&#8217;s where Underscore&#8217;s templating engine comes in.  In our app JavaScript code, we can then take action like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</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;">'#item-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></pre></div></div>

<p>The <code>$('#item-template')</code> code uses jQuery to reference the <code>script</code> element. Calling <code>html()</code> on the element then returns the inner html of the element&#8211;in this case the html that will represent a todo item.  Here comes the underscore templating engine: <code>_.template()</code>.  At this point a <em>compiled template</em> has been built.  This allows us to now pass a <em>context object</em> into the compiled template to produce html we can then use for our todo item.  This might look like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> todoHTML <span style="color: #339933;">=</span> template<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>done<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The portions of the template that depend on the <code>done</code> variable will be evaluated using the <code>done</code> property on the context object.  The resulting <code>todoHTML</code> will be a string of html that looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;todo done&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;display&quot;</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;check&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;checkbox&quot;</span> <span style="color: #000066;">checked</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;checked&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;todo-text&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</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;todo-destroy&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">span</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;edit&quot;</span>&gt;</span>
		<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;todo-input&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</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;">div</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></pre></div></div>

<p>You can then use jQuery to create an element out of the html.  It&#8217;s as easy as</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> element <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>todoHTML<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I should mention that a portion of this code is pulled from <a href="http://documentcloud.github.com/backbone/" target="_blank">Backbone.js</a>&#8216;s <a href="http://documentcloud.github.com/backbone/examples/todos/index.html" target="_blank">Todos example</a>.</p>
<h3>Template management</h3>
<p>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.  If you&#8217;ve asked yourself these things, congratulations!  These are questions architects should be asking.  We&#8217;ll talk about how to manage this in a later post.</p>
<h3>Templating syntax</h3>
<p>Underscore by default uses ERB-style template syntax (<code><%=...%></code>) which to me feels nasty and isn&#8217;t fun to type. You can change that to some other style like <code>{{...}}</code> as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">_.<span style="color: #660066;">templateSettings</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  interpolate <span style="color: #339933;">:</span> <span style="color: #009966; font-style: italic;">/\{\{(.+?)\}\}/g</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Much better.</p>
<h3>Other templating engines</h3>
<p>The concept of a templating engine is not unique to Underscore or even JavaScript.  There are many others in many languages.  I feel the most notable ones in JavaScript outside of Underscore are <a href="http://mustache.github.com/" target="_blank">Mustache.js</a> and <a href="http://www.handlebarsjs.com/" target="_blank">Handlebars.js</a>.  I use Underscore because it&#8217;s a top-notch templating engine, includes other Underscore functionality I use anyway, and it&#8217;s a dependency of <a href="http://documentcloud.github.com/backbone/" target="_blank">Backbone.js</a> which we&#8217;ll be discussing in a later post.</p>
<h3>Where to use templates</h3>
<p>After reading this, you may think templates are only appropriate for elements whose count is undetermined until runtime like our todo items. If so, may I suggest considering that everything should be a template?</p>
<p>What if you took everything in your body tag, broke it up into reasonably small templates, and left your body tag with nothing in it except for your templates?  What if each DOM element and its contents produced from each small template were managed by a single JavaScript object?  What kind of freedom would that bring your code?  Could you move these components around more freely?  Ship them over to be used in a different app?  Would they be less coupled from one another and provide stronger APIs? Could you more appropriately add, remove, re-arrange, and manipulate these components rather than having a big fat HTML file written up front?  Could you provide your users an all-around more dynamic experience?  I hope you catch the vision.  In upcoming posts we&#8217;ll see how this takes shape.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-underscore-js/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: jQuery</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-jquery/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-jquery/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 05:03:23 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cdn]]></category>
		<category><![CDATA[content delivery network]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[utility]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1090</guid>
		<description><![CDATA[jQuery is not an application framework. It is a toolbox&#8211;a set of utilities. If it could receive the label of &#8220;framework&#8221; at all it would be a utility or widget framework&#8211;not an application framework. In my experience and the experiences of others, far too many JavaScript noobs hear all about the powers of jQuery and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jquery.com" target="_blank">jQuery </a>is not an application framework. It is a toolbox&#8211;a set of utilities.  If it could receive the label of &#8220;framework&#8221; at all it would be a utility or widget framework&#8211;not an application framework.</p>
<p>In my experience and the experiences of others, far too many JavaScript noobs hear all about the powers of jQuery and how it can do this and that and pull rabbits out of a hat.  I do not dispute its awesomeness.  What follows, though, is that some developers feel it is the answer to all their problems&#8211;including architecture.  They then start busting out apps only using jQuery with little or no thought given to architecture because, in their mind, they&#8217;re already &#8220;using a framework&#8221; or &#8220;using an architecture.&#8221;  This may work for a brochure website with little interaction or state, but not for large, enterprise apps where greater structure is needed.</p>
<p>We&#8217;ll dig deeper into application frameworks, architecture, patterns, and all that juicy stuff later.  For now, I just want you to have an understanding of where jQuery fits into the picture lest you stray before we get into the meat.<span id="more-1090"></span></p>
<h3>What does jQuery do?</h3>
<p>It abstracts the mess that is the <a href="http://en.wikipedia.org/wiki/Document_Object_Model" target="_blank">DOM</a>.  DOM stands for Document Object Model and consists of elements and element hierarchies that make up a web page.  When manipulating elements on a page (form elements, containers, text, etc.), you somehow need to be able to find these elements, size them, position them, style them, animate them, add them, remove them, watch for events from them, and a plethora of other operations.  Without jQuery, this is a mess.  For one, the DOM and its APIs are quite poor in general.  Second, standards love to be ambiguous and browsers love to stray from standards.  jQuery abstracts this into simple-to-use APIs so you can be more efficient and waste less time dealing with browser inconsistencies and the dag-nasty that is the DOM.</p>
<p>jQuery also provides a great set of utilities for making <a href="http://en.wikipedia.org/wiki/Ajax_(programming)" target="_blank">ajax</a> requests and dealing with objects, arrays, strings, and more.  Many other utilities and widgets are built on top of jQuery including jQuery&#8217;s own <a href="http://jqueryui.com/" target="_blank">jQuery UI</a>.</p>
<h3>Who uses jQuery?</h3>
<p>jQuery is very popular.  According to <a href="http://trends.builtwith.com/" target="_blank">BuiltWith</a>, jQuery is <a href="http://trends.builtwith.com/javascript/jQuery" target="_blank">used on over 24 million websites</a>.  To avoid copyright infringement I won&#8217;t include their chart here, but I advise you to <a href="http://trends.builtwith.com/javascript/jQuery" target="_blank">take a look</a> if you&#8217;re interested.  You&#8217;ll see that over half of the top 10,000 sites use jQuery and this number is growing at a very steady pace.</p>
<h3>Content Delivery Networks</h3>
<p>This popularity not only exemplifies itself with a thriving community but also reaps the benefits of exposure through a <a href="http://en.wikipedia.org/wiki/Content_delivery_network" target="_blank">content delivery network</a>.  A CDN exposes assets at strategic places both geographically and network-topographically on well-tuned servers.  This boils down to three points of awesome:</p>
<ol>
<li>The files will be delivered quickly.</li>
<li>Some browsers limit the number of concurrent connections <em>to a given hostname</em>.  A CDN will be a different hostname from that which hosts your main application assets resulting in additional concurrent pipes open for transferring data to your user&#8217;s browser.</li>
<li>Browsers cache files based on their URL.  If a user goes to Site A that loads its jQuery from CDN X and then navigates to Site B that also loads its jQuery from CDN X, the user&#8217;s browser will likely not have to load jQuery a second time since it can be retrieved from its cache.</li>
</ol>
<p>Google provides <a href="http://encosia.com/6953-reasons-why-i-still-let-google-host-jquery-for-me/" target="_blank">the most popular CDN for jQuery</a>.  You can see the most popular libraries it hosts as well as the URLs you can use to load them <a href="http://code.google.com/apis/libraries/devguide.html#Libraries" target="_blank">here</a>.  Given that many of the web&#8217;s largest sites use the Google CDN for jQuery, it&#8217;s very likely your users will be able to take advantage of cross-site caching.</p>
<p>Many of the other libraries we will be talking about may not be hosted by Google, but are hosted by <a href="http://www.cdnjs.com/" target="_blank">cdnjs</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: Organization and Quality</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-organization-and-quality/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-organization-and-quality/#comments</comments>
		<pubDate>Tue, 06 Dec 2011 05:14:46 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[cohesion]]></category>
		<category><![CDATA[conventions]]></category>
		<category><![CDATA[decoupling]]></category>
		<category><![CDATA[jshint]]></category>
		<category><![CDATA[jslint]]></category>
		<category><![CDATA[jstestdriver]]></category>
		<category><![CDATA[qunit]]></category>
		<category><![CDATA[scope]]></category>
		<category><![CDATA[strict mode]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1040</guid>
		<description><![CDATA[Never build large apps Justin Meyer, the main guy behind JavaScriptMVC, said something I feel is a very simple principle every architect should ingrain into their brain: The secret to building large apps is NEVER build large apps. Break up your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application. [...]]]></description>
			<content:encoded><![CDATA[<h3>Never build large apps</h3>
<p>Justin Meyer, the main guy behind <a href="http://javascriptmvc.com/" target="_blank">JavaScriptMVC</a>, <a href="http://jupiterjs.com/news/organizing-a-jquery-application" target="_blank">said something</a> I feel is a very simple principle every architect should ingrain into their brain:</p>
<blockquote><p>
The secret to building large apps is NEVER build large apps. Break up your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application.
</p></blockquote>
<p>I don&#8217;t think any other principle will carry more weight in architecture&#8211;especially with JavaScript.  You may be thinking, &#8220;Oh, my application isn&#8217;t big enough to follow this principle.&#8221;  Re-think this.  Every application I&#8217;ve architected&#8211;even the smallest of the small&#8211;have benefited from this principle.  The pieces of your application <em>must</em> be <a href="http://en.wikipedia.org/wiki/Decoupling#Software_Development" target="_blank">decoupled</a> and <a href="http://en.wikipedia.org/wiki/Cohesion_(computer_science)" target="_blank">cohesive</a> as much as humanly possible to withstand the test of time.  Each piece should be as black-box as possible&#8211;pass information over the wall and the next component does its job.  And I don&#8217;t just mean different views of your app; I also mean individual, small components of your views, models, and everything you build.  This presentation on <a href="http://www.slideshare.net/nzakas/scalable-javascript-application-architecture" target="_blank">Scalable JavaScript Application Architecture</a> does a great job of explaining these principles in more detail.<span id="more-1040"></span></p>
<p>When you think of JavaScript apps you may think of a few gigantic, spaghetti JavaScript files and a few beefy HTML files and a mess throughout.  You might even think of fat strings of html text hand-concanated, escaped, and declared right within your JavaScript.  <a href="http://jstorimer.com/2012/01/09/the-hungry-programmer.html" target="_blank">Escape this mindset.</a>  That, indeed, is a rightful stigma of JavaScript apps because so many exist that fall into this category.  We&#8217;re not going to be following that trend.  We want to favor many small classes, files, and HTML templates over a few large ones.  Small classes lead to small scope.  Small scope leads to better maintainability and easier debugging because there is less your mind needs to comprehend.  It also encourages strong, well-planned APIs and low coupling.</p>
<p>You may be thinking, &#8220;But JavaScript doesn&#8217;t have namespaces and everything&#8217;s asynchronously loaded and depends on everything else!  And what about all the requests to the server? And how do I get all those HTML templates into my app?  This is going to be a nightmare!&#8221;  Don&#8217;t worry about it.  We&#8217;ll get there.  Don&#8217;t fall into the trap of making excuses for poor design just because you&#8217;re in JavaScript.</p>
<h3>Admit what you don&#8217;t know</h3>
<p>The only thing that&#8217;s guaranteed not to change is change.  Therefore, never act like you know how your app will grow and change.  Nicholas Zakas <a href="http://radar.oreilly.com/2011/06/big-javascript-apps-teams.html" target="_blank">said it</a> well:</p>
<blockquote><p>
The key is to acknowledge from the start that you have no idea how this will grow. When you accept that you don&#8217;t know everything, you begin to design the system defensively.
</p></blockquote>
<h3>Naming conventions</h3>
<p>There are many conventions in JavaScript&#8211;some more popular than the others.  I find it important to maintain consistency with most JavaScript code out there.  Unfortunately, I haven&#8217;t found empirical evidence showing which conventions are most popular, but I have done some rudimentary research and will propose a few seemingly most-popular conventions.  Again, these are only suggestions.  The most important point is that you agree on a standard as a team and stay consistent.</p>
<ul>
<li>Names of directories and files should be all lowercase.  Add hyphens between words.</li>
<li>Variable names should be <a href="http://en.wikipedia.org/wiki/CamelCase">camelCase</a>.</li>
<li>Objects (functions) meant to be instantiated should start with a capital letter.</li>
<li>Private scope doesn&#8217;t exist in JavaScript except through closures.  See the poorly-named <a href="http://yuiblog.com/blog/2007/06/12/module-pattern/" target="_blank">module pattern</a> for more info but I <a href="http://snook.ca/archives/javascript/no-love-for-module-pattern" target="_blank">don&#8217;t really love the consequences of the pattern</a>.  Instead, I suggest prefixing names of members meant to be private with an underscore.  It doesn&#8217;t provide true privacy, but it&#8217;s a pretty solid red flag that you shouldn&#8217;t use it publicly.</li>
</ul>
<h3>Testing</h3>
<p>Strongly-typed languages (e.g., Java, C#, ActionScript 3) specify the type of each variable throughout the application.  This means the compiler can raise red flags when you try to use an object in a manner that wasn&#8217;t intended by its type.  In essence, strong typing can be considered to be a bunch of built-in, simple unit tests that are run each time the app is compiled.</p>
<p>JavaScript is not a strongly-typed language but instead is a very loosely-typed language.  It&#8217;s much easier to make mistakes by using objects in ways that weren&#8217;t intended or just fat-fingering a variable name and you won&#8217;t find out about it until you run the code and see the error (a good IDE can also help).  For this reason, I believe testing is even more important in loosely-typed languages.</p>
<p>There are many JS libraries available to help you test your code.  <a href="http://docs.jquery.com/QUnit" target="_blank">QUnit</a> seems to work well and is popular.  If you don&#8217;t already have a favorite, I suggest to start there and research outward.</p>
<p><a href="http://code.google.com/p/js-test-driver/wiki/GettingStarted" target="_blank">JsTestDriver</a> can also be very useful (and happens to have a <a href="http://code.google.com/p/js-test-driver/wiki/QUnitAdapter" target="_blank">QUnit adapter</a>).  JsTestDriver allows you to run your tests within a variety of browsers.  This can be very helpful since browsers aren&#8217;t consistent in their implementation.  For example, I might write code using <code>myArray.indexOf()</code> which will work on most browsers but not older Internet Explorers.  By running your tests within actual browsers these issues will crop up and you&#8217;ll find out about them before your users do.</p>
<h3>Strict mode</h3>
<p>The 5th version of <a href="http://en.wikipedia.org/wiki/ECMAScript" target="_blank">ECMAScript</a> (the standard upon which JavaScript is based) provides an option with which you can tell browsers to be more strict with your code.  Newer browsers will respect it while older browser will stay lenient.  Why would you want browsers to be <em>more</em> strict with your code?  Because you want to decrapify your code.  Strict mode provides the following (<a href="https://developer.mozilla.org/en/JavaScript/Strict_mode" target="_blank">copied from MDN</a>):</p>
<ul>
<li>Strict mode eliminates some JavaScript pitfalls that didn&#8217;t cause errors by changing them to produce errors.</li>
<li>Strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that&#8217;s not strict mode (Firefox 4 generally hasn&#8217;t optimized strict mode yet, but subsequent versions will).</li>
<li>Strict mode prohibits some syntax likely to be defined in future versions of ECMAScript.</li>
</ul>
<p>I highly recommend <a href="https://developer.mozilla.org/en/JavaScript/Strict_mode#Invoking_strict_mode" target="_blank">invoking strict mode</a> to keep your code squeaky clean.</p>
<h3>Code Analysis Tools</h3>
<p>A couple popular code analysis tools exist to likewise help decrapify your code.  They scan your code and raise flags when they see you&#8217;ve done something dangerous or undesirable.  They mainly focus on syntax, style, and structure.  They do not verify that your logic is correct.</p>
<p>The first is <a href="http://www.jslint.com/" target="_blank">JSLint</a>.  It&#8217;s &#8220;the original&#8221;.  The second is <a href="http://www.jshint.com/" target="_blank">JSHint</a>.  JSHint explains the difference:</p>
<blockquote><p>
JSHint is a fork of JSLint, the tool written and maintained by Douglas Crockford.</p>
<p>The project originally started as an effort to make a more configurable version of JSLint—the one that doesn&#8217;t enforce one particular coding style on its users—but then transformed into a separate static analysis tool with its own goals and ideals.
</p></blockquote>
<p>Both tools have online versions where you can copy-paste a snippet into a textarea and have the code analysis do its thing.  This works okay for bits of code here and there, but even better is setting up the analysis code to run on your full app.  Both tools have integrations to you allow you to analyze your app&#8217;s code from your IDE or command line.  On our team, we run the tool from an Ant script that we can then run from the command line, our IDE, or our deployment servers.  I highly recommend you run these tools often right off the bat.  Note that each have flags you can set to be more or less strict in its analysis.</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-organization-and-quality/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>JavaScript Architecture: The Basics</title>
		<link>http://aaronhardy.com/javascript/javascript-architecture-the-basics/</link>
		<comments>http://aaronhardy.com/javascript/javascript-architecture-the-basics/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 00:06:18 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[architect]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[RIA]]></category>
		<category><![CDATA[WebStorm]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1022</guid>
		<description><![CDATA[This post is intended to be the first of a series. I want to be clear about what it entails and its intended audience. For the past several years I&#8217;ve been an architect in enterprise-level RIAs. This is a fancy way of saying I oversee the design and construction of apps that are web-based but [...]]]></description>
			<content:encoded><![CDATA[<p>This post is intended to be the first of a series.  I want to be clear about what it entails and its intended audience.</p>
<p>For the past several years I&#8217;ve been an architect in enterprise-level RIAs.  This is a fancy way of saying I oversee the design and construction of apps that are web-based but have a lot of the same characteristics as desktop applications.  Some of the applications I work on <i>are</i> in fact desktop applications but heavily communicate with the web.  The line becomes very blurry, but the main point is&#8211;I deal with <i>applications</i> which in my world are quite different than what is often considered a &#8220;website&#8221; even though they both live within a browser.</p>
<p>There are others in the industry who do what I do or would like to do what I do.  Of those there are some who are new to JavaScript.  This is my intended audience.  An architect arriving at JavaScript for the first time has a lot to learn and many decisions to make.  As the lead architect on a product and being fairly new to JavaScript (well, modern JavaScript) I likewise had to go through this process and have spent countless hours re-learning JavaScript, testing IDEs, discovering communities, exploring deployment procedures, learning what questions to ask, evaluating libraries (mvc, dependency management, dom manipulation, testing, deployment, utilities) and putting all these things together to lead a team and produce an application worthy of enterprise consumption. My hope is to help others along the way.<span id="more-1022"></span></p>
<p>You might think this is a broad effort, but my goal is not to simply regurgitate everything I&#8217;ve learned but to help boil things down to what&#8217;s important to get you on your way.  We&#8217;ll discuss core principles that are common in dynamic apps regardless of the languages or libraries used.  However, to illustrate them and hopefully give you enough of a concrete example to help you hit the ground running, I&#8217;ll be using specific, hand-picked libraries for this series.  In your own research you may find other libraries are more appropriate for your particular project.  That&#8217;s fine; the principles in this series are still valuable and applicable.</p>
<h3>Choose wisely</h3>
<p>JavaScript is merely a language.  HTML is, for the most part, a set of dilapidated, relatively primitive components.  To reduce boilerplate, abstract browser inconsistencies, and provide engineers with higher-level tools to be more productive, all kinds of libraries have come out of the woodwork.  Because JavaScript and HTML leave out some basic structures and components that are so commonly needed, these libraries often overlap in functionality and features.  This also means some don&#8217;t play well together.  This is both exciting because you have so many options to choose from and yet frustrating because you have so many options to choose from.</p>
<p>As an architect, specifically in an enterprise setting, these decisions will be very important and can ultimately determine the fate of your product. If I were farting around on a side-project, I&#8217;d probably feel comfortable picking the most awesome-sounding libraries and running with them.  In the corporate world though, we have to answer some important questions:  Is our product part of a larger suite?  If so, what is the rest of the suite using?  If the rest of the suite were to standardize on a particular library, how hard would it be for us to refactor?  What if we chose a &#8220;full-stack&#8221; library and a portion of it is or becomes inferior to other options?  What&#8217;s the chance that a different library may overtake my library in community and technical progression?  What&#8217;s the community like around those libraries?  Which libraries are gaining steam or fizzling out?  What&#8217;s their learning curve? How easy is it to hire developers for these libraries?  It&#8217;s a very different ballgame so take care in your decisions. In my case, I found the best option was to pick a handful of high-quality tools with healthy communities that worked well together but were decoupled in their implementations.  <a href="http://grooveshark.com/" target="_blank">Grooveshark</a> provides <a href="http://blog.jerodsanto.net/2010/12/the-tech-behind-the-new-grooveshark/" target="_blank">a very interesting related case study</a>.</p>
<h3>Rolling your own</h3>
<p>There comes a time in every developer&#8217;s life where we get caught up in rolling our own libraries.  Maybe we think our work is superior, maybe we don&#8217;t do enough research on what&#8217;s already available, or maybe there&#8217;s just one small thing that isn&#8217;t quite right in a library so we rewrite it from scratch.  I&#8217;ve done it and you likely have too.  When determining what your team will use, it&#8217;s very important to keep in mind some of the significant benefits of going with a wisely-chosen 3rd-party/open-source library:</p>
<ul>
<li>Free development resources</li>
<li>Free documentation</li>
<li>Free bug fixes</li>
<li>Free testing by automated tests and other community members</li>
<li>Collaboration amongst generally intelligent industry leaders</li>
<li>A place to learn more and ask questions</li>
</ul>
<p>Far too often I&#8217;ve seen very intelligent architects roll their own libraries because they feel their skills are superior or are OCD that the libraries work exactly like they want and carries no extra baggage.  Very often, if that architect were to stay on the project forever, this would probably work out quite well and the product would be successful.  In reality, the architect leaves.  Almost always they were time-crunched and didn&#8217;t fully document the library, set up testing, or cross-train their co-workers.  They developed the library for the purpose of fulfilling the specific needs of a project and even though the library may have been a fantastic work of art, the engineers left with that work of art don&#8217;t understand its intended usage or how to make modifications.  From there, the engineers begin using it incorrectly and if they have questions they have nobody to ask and nowhere to look except for undocumented, increasingly morbid code.  Inevitably, the product starts its death-spin, the engineers blame the architect that left, and technical debt grows until the product declares bankruptcy.  At this point it&#8217;s time to rebuild or sink.</p>
<p>Truthfully, most of the fault really does fall on the architect.  The role of the architect is not only to code awesomeness, but also to understand the software circle of life and make wise decisions.</p>
<p>Don&#8217;t get me wrong&#8211;there is a time and place for rolling our own libraries.  If you come across this time and place, make sure you have the necessary resources behind it.  Do it right.  Where possible, create the libraries as though other companies might also use them.  Document them&#8211;not only in code but in API documents, examples, and tutorials.  Open-source them on <a href="https://github.com/" target="_blank">GitHub</a> and make it a home for external resources to congregate around and contribute.  Pay attention to others&#8217; contributions and incorporate their ideas and code where possible.  Many if not most of the great libraries available today originated from this concerted effort.</p>
<p>One last note about open-source libraries.  The historical perception is that these libraries are siloed away in some remote part of the web and their developers are anonymous and unapproachable.  This usually isn&#8217;t the case anymore&#8211;especially with GitHub.  Oftentimes if you have a legitimate concern the community is very approachable and will respond quickly and respectfully.  A great example of this is when I recently found that <a href="http://documentcloud.github.com/underscore/" target="_blank">underscore.js</a> lacked a function for finding the symmetric difference between multiple arrays.  I provided the underscore.js community an example of where it would be beneficial and <a href="https://github.com/documentcloud/underscore/pull/309#issuecomment-2852147" target="_blank">five days later it was added to the trunk with a unit test and documentation</a>.  Good libraries have good communities.  Choose wisely.</p>
<h3>We don&#8217;t need no stinkin&#8217; frameworks!</h3>
<p>A long-standing debate among some in the community is whether formal frameworks are needed at all.  The argument against frameworks usually goes something like, &#8220;We&#8217;re all smart engineers&#8211;we can architect an app well without having to resort to a formal framework.&#8221;  That may be true, but it&#8217;s usually a fallacy.  If it&#8217;s not a fallacy, it&#8217;s very difficult to do with most teams.  If you are able to successfully execute on that concept, you very likely unconsciously re-wrote large portions of a framework you could have used in the first place.</p>
<p>When working in a team, a framework provides an important benefit of consistency and a game plan.  Good frameworks generally prescribe examples of best-practice usage but provide some flexibility in implementation.  No doubt engineers can abuse the best of frameworks, but having a blueprint of how architecture and implementation should, in general, be performed goes a long way in getting everyone on the team to have a consistent vision and understanding.</p>
<h3>Learn JavaScript</h3>
<p>Learning JavaScript is not a one-time event.  You&#8217;ll be learning over a long period of time, but it&#8217;s important that you actually make it a priority to learn the language.  A lot of the libraries we&#8217;ll be looking at do a lot of abstracting for you&#8211;keeping you away from the nitty-gritty of JavaScript.  That&#8217;s very helpful and can speed up your development dramatically, but it should not be used as a crutch.  Far too often people learn libraries but not the language.  This is a mistake and will bite you in the end.</p>
<p>I&#8217;ll be the first to admit that JavaScript has some really nasty parts.  Frankly, it&#8217;s not my favorite language.  But you&#8217;ll be living in it.  Accept it and learn how to take advantage of its good parts and avoid its bad parts.  To that end, I recommend starting with Douglas Crockford&#8217;s <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742" target="_blank">JavaScript: The Good Parts</a>.  Ironically, it&#8217;s a small book and very approachable by JavaScript noobs.</p>
<h3>IDE</h3>
<p>Get yourself a quality development environment.  If we&#8217;re talking web we&#8217;re primarily talking HTML, JavaScript, and CSS.  There are all kinds of free web-oriented IDEs (<a href="http://aptana.com" target="_blank">Aptana</a> comes to mind) but I recommend you pick up a copy of <a href="http://www.jetbrains.com/webstorm/" target="_blank">WebStorm</a> by <a href="http://www.jetbrains.com" target="_blank">JetBrains</a>.  A good IDE will give you great JavaScript code-hinting to shield you from some of the woes that come with the dynamically-typed language.  Other things I look for: coding workflow, local and remote debugging, version control integration, remote server deployment, plugins, etc.</p>
<p>Have comments or questions?  Post them below!</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/javascript/javascript-architecture-the-basics/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<series:name><![CDATA[JavaScript Architecture]]></series:name>
	</item>
		<item>
		<title>Dear Intermountain Healthcare</title>
		<link>http://aaronhardy.com/life-in-general/dear-intermountain-healthcare/</link>
		<comments>http://aaronhardy.com/life-in-general/dear-intermountain-healthcare/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 04:25:34 +0000</pubDate>
		<dc:creator>Aaron Hardy</dc:creator>
				<category><![CDATA[Life in General]]></category>

		<guid isPermaLink="false">http://aaronhardy.com/?p=1006</guid>
		<description><![CDATA[Dear Intermountain Healthcare, Over the last two years we&#8217;ve become frequent fliers at your hospitals. Our daughter has an undiagnosed Leukodystrophy and, as such, reacts abnormally to or has a difficult time fighting off the variety of ailments that beset her. She is tube fed, immobile, and unable to speak. A week ago we were [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Intermountain Healthcare,</p>
<p>Over the last two years we&#8217;ve become frequent fliers at your hospitals.  Our daughter has an undiagnosed <a href="http://en.wikipedia.org/wiki/Leukodystrophy" target="_blank">Leukodystrophy</a> and, as such, reacts abnormally to or has a difficult time fighting off the variety of ailments that beset her.  She is tube fed, immobile, and unable to speak.  A week ago we were on a family vacation in Idaho and she became very sick.  She began vomiting frequently and couldn&#8217;t retain the smallest amounts of liquid.  Her skin felt hot and she appeared extremely lethargic.  We took her to the IHC emergency room in Burley, ID to get her the help she needed.</p>
<p>Three times while in the emergency room we recounted the events that had occurred leading up to our arrival and the history of our daughter&#8217;s Leukodystrophy.  Eventually tests were ran which showed low glucose levels and an extraordinarily high heart rate&#8211;both symptoms of dehydration.  She was given fluids and glucose to a point where she seemed to be responding well enough for us to cut our vacation short and make our way back home. They directed that if there were any problems in the meantime to be sure to take her to the nearest emergency room.<span id="more-1006"></span></p>
<p>The trip back home is approximately four hours.  During the trip home she moaned in a way that seemed to express pain but we figured it may be a result of the trauma she had endured over the past day.  When we got home, she was acting very similar to how she was before we took her to the hospital earlier.  She was very unresponsive and resisted opening her eyes or making any movement.  When we tried giving her a few drops of water in her mouth using a wet sponge she immediately vomited.  Again her heart rate was elevated and her skin felt hot.  It was obvious something was wrong and she needed liquids fast.  We rushed to the IHC emergency room in American Fork, UT about five minutes away.</p>
<p>The lobby was empty and it did not appear as though many, if any, patients were being attended to within the ER.  I showed the secretary our unresponsive daughter and requested that fluids be provided quickly and that we already knew she was dealing with dehydration.  Again we were asked to explain the events that had occurred&#8211;not only since our trip to the IHC hospital earlier in the day but also the events previous and the circumstances surrounding her Leukodystrophy.  We were asked to explain the same to the nurse who took her vitals, weight, etc.  Ten minutes had passed and no liquids had been requested.</p>
<p>We were brought back to the emergency room where a different nurse cheerfully chatted with our newborn son who we had brought in the car seat, asked what his name was, and when he was born.  By all means, she had a heart of gold and I would love to bring in my photo albums so she could get acquainted with my family tree, but my daughter continued declining and, as though I should have to point out, we&#8217;re in the emergency room!  Again, we were asked to recount the history of events and details of her Leukostrophy.  We made sure this nurse, too, was aware our daughter needed liquids ASAP.</p>
<p>Twenty minutes into our hospital visit the doctor came in.  Again we were asked to recount the history of events and details of our daughter&#8217;s Leukostrophy.  A half hour had passed since we entered the emergency room and no fluids were to be seen.  On the flip side, I was able to partake in the reminiscing of recent class reunion hilarity that ensued at the nurse&#8217;s station while my daughter continued on the decline.  Nay, not only that, but I was able to graciously provide my credit card to pay for care we had not yet received, look for insurance cards that turned out to already be in the system, and for the fourth time answer such urgent and diagnostic questions as &#8220;And who&#8217;s your employer?&#8221;</p>
<p>I pitched a fit. I made a scene. I&#8217;m sincerely not one to get upset easily or desire to make any sort of disturbance especially in a place of healing.  But that day I did everything in my power to ensure your employees knew we were in an emergency room and there was an emergency to be treated.  The doctor&#8217;s response: &#8220;Your child isn&#8217;t going to die if we don&#8217;t give her fluids right away.&#8221;  Is that so?  Were those your findings the last time you treated an undiagnosed Leukodystrophy patient suffering from severe dehydration the previous doctors thought they had under control?  Why are we in the emergency room at all then?  Who cares if her energy is sapped to render her unable to avoid aspirating her own vomit?  Who cares if her system continues shutting down or her body starts eating away the little muscle she has.  Send us home with a bottle of water or maybe I can call in my extended family and we can all kick back and talk about who our employers are!  Hell&#8217;s bells&#8211;I&#8217;d venture at least 95% of the people going into the emergency room wouldn&#8217;t die if we sat on our hands for a while.  Let&#8217;s all go have a coffee break, shall we?</p>
<p>After finally getting her hooked up to fluids and reviewing some of her tests she took an ambulance ride to the IHC Primary Chidren&#8217;s Hospital in Salt Lake City, UT.  We repeated the routine.  Two more times we described the events.  Two more times we gave the history of her Leukodystrophy.  Two more times I answered who my employer was and a handful-dozen other questions I had answered several times previously that same day.  Our daughter was hospitalized for three days following to be treated and recover from what appeared to be an intestinal virus.</p>
<p>I realize this may be entirely ignored or we may be discredited as over-dramatic parents.  Or, on the other hand, you might consider the improvements that could be made, a higher standard that could be achieved, or that patients might be able to arrive at your hospitals with the expectation of timely treatment and professional service.</p>
<p>Sincerely,</p>
<p>Aaron Hardy</p>
]]></content:encoded>
			<wfw:commentRss>http://aaronhardy.com/life-in-general/dear-intermountain-healthcare/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

