summaryrefslogtreecommitdiffstats
path: root/pygments/organizing-backbone-using-modules/index.html
blob: 69c9f4634013861354fa6cc4bc74fe9818727241 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<meta name="readability-verification" content="QaMWXDtxjtrFwfPQ2an55eWRMRLr7F2ermV5E9ch"/> 
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
   <title>Organizing your application using Modules (require.js) - Backbone.js Tutorials</title>
<link href="/atom.xml" rel="alternate" title="backbone tutorials" type="application/atom+xml">
   <meta name="author" content="Backbone Tutorials" />

   <!-- syntax highlighting CSS -->
   <link rel="stylesheet" href="/css/reset.css" type="text/css" />

   <!-- syntax highlighting CSS -->
   <link rel="stylesheet" href="/css/syntax.css" type="text/css" />
   
   <!-- github ribbon CSS -->
   <link rel="stylesheet" href="/css/ribbon.css" type="text/css" />

   <!-- Homepage CSS -->
   <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen, projection" />
   
   <!-- Homepage CSS -->
   <link rel="stylesheet" href="/css/stacklayout.css" type="text/css" media="screen, projection" />

   <!-- Typekit -->
   <script type="text/javascript">try{Typekit.load();}catch(e){}</script>
 
    <style>
        .container {
            width: 760px;
            margin: auto;
        }
        .menu {
            margin-left: 40px;
            padding-top: 10px;
            padding-bottom: 10px;
        }
        .menu a {
            margin-right: 10px;
        }
        p {
            width: 720px;
            margin: auto;
        }
        .FlattrButton {
			position: absolute;
			top: 15px;
			right: 15px;
		}
    </style>
    <script type="text/javascript">
/* <![CDATA[ */
    (function() {
        var s = document.createElement('script'), t = document.getElementsByTagName('script')[0];
        s.type = 'text/javascript';
        s.async = true;
        s.src = 'http://api.flattr.com/js/0.6/load.js?mode=auto';
        t.parentNode.insertBefore(s, t);
    })();
/* ]]> */
</script>
</head>
<body>
   <div class="left ribbon-holder">
        <a href="https://github.com/thomasdavis/backbonetutorials" class="red ribbon">
          <span class="text">Fork on GitHub</span>
        </a>
      </div>
      
     <a class="FlattrButton" style="display:none;" href="http://backbonetutorials.com/"></a>
<noscript><a href="http://flattr.com/thing/176986/Backbone-js-Tutorials" target="_blank">
<img src="http://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0" /></a></noscript>

<div class="container">
            <div class="menu">
            <a href="/">home</a>
            <a href="/examples.html">examples</a>
            <!-- <a href="/contribute.html">contribute</a>-->
            <a href="/about.html">about</a>
            <a href="http://feeds.feedburner.com/BackboneTutorials">subscribe</a>
            <a style="margin-left: 320px;" href="http://pledgie.com/campaigns/16174"><strong>donate</strong></a>
          </div>
          
                    
         
          
    <div class="stack">
        <div class="stackContent">
            <h1>Backbone Tutorials</h1>
            <p class="homepagedescription">This site is by no means the definitive guide to backbone.js and all corrections and contributions are welcome.</p>
            
<a style="margin-left: 20px;" href="https://twitter.com/neutralthoughts" class="twitter-follow-button">Follow @neutralthoughts</a>
<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script>

            <hr>
             <div id="post">
<h2>Organizing your application using Modules (require.js)</h2>
<p>Unfortunatly Backbone.js does not tell you how to organize your code leaving many developers in the dark regarding how to load scripts and lay out their development enviroments.</p>
<p>This was quite a different decision to other Javascript <span class="caps">MVC</span> frameworks who were more in favor of setting a development philosophy.</p>
<p>Hopefully this tutorial will allow you to build  a much more robust project with great separation of concerns between design and code.</p>
<p>This tutorial will get you started on combining Backbone.js with <a href="https://github.com/amdjs/amdjs-api/wiki/AMD"><span class="caps">AMD</span></a> (Asynchronous Module Definitions).</p>
<h3>What is <span class="caps">AMD</span>?</h3>
<p><a href="https://github.com/amdjs/amdjs-api/wiki/AMD">Asynchronous Module Definitions</a> designed to load modular code asynchronously in the browser and server.   It is actually a fork of the Common.js specification.   Many script loaders have built their implementations around <span class="caps">AMD</span>, seeing it as the future of modular Javascript development.</p>
<p>This tutorial will use <a href="http://requirejs.org">Require.js</a> to implement a modular and organized Backbone.js.</p>
<p><b>I highly recommend using <span class="caps">AMD</span> for application development</b></p>
<p>Quick Overview</p>
<ul>
	<li>Modular</li>
	<li>Scalable</li>
	<li>Compiles well(see <a href="http://requirejs.org/docs/optimization.html">r.js</a>)</li>
	<li>Market Adoption( <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 converted fully to <span class="caps">AMD</span></a> )</li>
</ul>
<h3>Why Require.js?</h3>
<p>Require.js has a boastful community and is growing rapidly.  <a href="http://tagneto.blogspot.com/">James Burke</a> the author is married to Require.js and responds to user feedback always.   A leading expert in script loading, he is also a contributer to the <span class="caps">AMD</span> specification.</p>
<p><a href="https://twitter.com/jrburke" class="twitter-follow-button">Follow @jrburke</a><br />
<script src="//platform.twitter.com/widgets.js" type="text/javascript"></script></p>
<h3>Getting started</h3>
<p>To easily understand this tutorial you should jump straight into the example code base.</p>
<h3><a href="https://github.com/thomasdavis/backbonetutorials/tree/gh-pages/examples/modular-backbone">Example Codebase</a></h3>
<h3><a href="http://backbonetutorials.com/examples/modular-backbone">Example Demo</a></h3>
<p>The tutorial is only loosely coupled with the example and you will find the example to be more comprehensive.</p>
<p>If you would like to see how a particuliar use case would be implemented please visit the Github page and create an issue.(Example Request: How to do nested views).</p>
<p>The example isn&#8217;t super fleshed out but should give you a vague idea.</p>
<h3>Example File Structure</h3>
<p>There are many different ways to lay out your files and I believe it is actually dependent on the size and type of the project.   In the example below views and templates are mirroed in file structure.  Collections and Models aren&#8217;t categorized into folders kind of like an <span class="caps">ORM</span>.</p>
<div class="highlight"><pre><code class="javascript"><span class="cm">/* File Structure</span>
<span class="cm">├── imgs</span>
<span class="cm">├── css</span>
<span class="cm">│   └── style.css</span>
<span class="cm">├── templates</span>
<span class="cm">│   ├── projects</span>
<span class="cm">│   │   ├── list.html</span>
<span class="cm">│   │   └── edit.html</span>
<span class="cm">│   └── users</span>
<span class="cm">│       ├── list.html</span>
<span class="cm">│       └── edit.html</span>
<span class="cm">├── js</span>
<span class="cm">│   ├── libs</span>
<span class="cm">│   │   ├── jquery</span>
<span class="cm">│   │   │   ├── jquery.min.js</span>
<span class="cm">│   │   │   └── jquery.js // jQuery Library Wrapper</span>
<span class="cm">│   │   ├── backbone</span>
<span class="cm">│   │   │   ├── backbone.min.js</span>
<span class="cm">│   │   │   └── backbone.js // Backbone Library Wrapper</span>
<span class="cm">│   │   └── underscore</span>
<span class="cm">│   │   │   ├── underscore.min.js</span>
<span class="cm">│   │   │   └── underscore.js // Underscore Library Wrapper</span>
<span class="cm">│   ├── models</span>
<span class="cm">│   │   ├── users.js</span>
<span class="cm">│   │   └── projects.js</span>
<span class="cm">│   ├── collections</span>
<span class="cm">│   │   ├── users.js</span>
<span class="cm">│   │   └── projects.js</span>
<span class="cm">│   ├── views</span>
<span class="cm">│   │   ├── projects</span>
<span class="cm">│   │   │   ├── list.js</span>
<span class="cm">│   │   │   └── edit.js</span>
<span class="cm">│   │   └── users</span>
<span class="cm">│   │       ├── list.js</span>
<span class="cm">│   │       └── edit.js</span>
<span class="cm">│   ├── router.js</span>
<span class="cm">│   ├── app.js</span>
<span class="cm">│   ├── main.js  // Bootstrap</span>
<span class="cm">│   ├── order.js //Require.js plugin</span>
<span class="cm">│   └── text.js  //Require.js plugin</span>
<span class="cm">└── index.html</span>

<span class="cm">*/</span>
</code></pre>
</div>
<p>To continue you must really understand what we are aiming towards as described in the introduction.</p>
<h3>Bootstrapping your application</h3>
<p>Using Require.js we define a single entry point on our index page.  <br />
We should setup any useful containers that might be used by our Backbone views.</p>
<p><b>Note</b>: The data-main attribute on our single script tag tells Require.js to load the script located at &#8220;js/main.js&#8221;.  It automatically appends the &#8220;.js&#8221;</p>
<div class="highlight"><pre><code class="html"><span class="cp">&lt;!doctype html&gt;</span>
<span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;head&gt;</span>
	<span class="nt">&lt;title&gt;</span>Jackie Chan<span class="nt">&lt;/title&gt;</span>
	<span class="c">&lt;!-- Load the script &quot;js/main.js&quot; as our entry point --&gt;</span>
	<span class="nt">&lt;script </span><span class="na">data-main=</span><span class="s">&quot;js/main&quot;</span> <span class="na">src=</span><span class="s">&quot;js/libs/require/require.js&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>

<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;container&quot;</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;menu&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;content&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>

<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre>
</div>
<p>You should most always end up with quite a light weight index file.   You can serve this off your server and then the rest of your site off a <span class="caps">CDN</span> ensuring that everything that can be cached, will be.</p>
<h4>What does the bootstrap look like?</h4>
<p>Our bootstrap file will be responsible for configuring Require.js and loading initially important dependencies.</p>
<p>In the below example we configure Require.js to create shortcut alias to commonly used scripts such as jQuery, Underscore and Backbone.</p>
<p>Due to the nature of these libraries implementations we actually have to load them in order because they each depend on each other existing in the global namespace(which is bad but is all we have to work with).</p>
<p>Hopefully if the <span class="caps">AMD</span> specification takes off these libraries will add code to allow themselves to be loaded asynchronously.   Due to this inconvience the bootstrap is not as intuitive as it could be, I hope to solve this problem in the near future.</p>
<p>We also request a module called &#8220;app&#8221;, this will contain the entireity of our application logic.</p>
<p><b>Note:</b> Modules are loaded relativly to the boot strap and always append with &#8220;.js&#8221;.   So the module &#8220;app&#8221; will load &#8220;app.js&#8221; which is in the same directory as the bootstrap.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: main.js</span>

<span class="c1">// Require.js allows us to configure shortcut alias</span>
<span class="c1">// There usage will become more apparent futher along in the tutorial.</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
  <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
    <span class="nx">jQuery</span><span class="o">:</span> <span class="s1">&#39;libs/jquery/jquery&#39;</span><span class="p">,</span>
    <span class="nx">Underscore</span><span class="o">:</span> <span class="s1">&#39;libs/underscore/underscore&#39;</span><span class="p">,</span>
    <span class="nx">Backbone</span><span class="o">:</span> <span class="s1">&#39;libs/backbone/backbone&#39;</span>
  <span class="p">}</span>

<span class="p">});</span>

<span class="nx">require</span><span class="p">([</span>

  <span class="c1">// Load our app module and pass it to our definition function</span>
  <span class="s1">&#39;app&#39;</span><span class="p">,</span>

  <span class="c1">// Some plugins have to be loaded in order due to there non AMD compliance</span>
  <span class="c1">// Because these scripts are not &quot;modules&quot; they do not pass any values to the definition function below</span>
  <span class="s1">&#39;order!libs/jquery/jquery-min&#39;</span><span class="p">,</span>
  <span class="s1">&#39;order!libs/underscore/underscore-min&#39;</span><span class="p">,</span>
  <span class="s1">&#39;order!libs/backbone/backbone-min&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">App</span><span class="p">){</span>
  <span class="c1">// The &quot;app&quot; dependency is passed in as &quot;App&quot;</span>
  <span class="c1">// Again, the other dependencies passed in are not &quot;AMD&quot; therefore don&#39;t pass a parameter to this function</span>
  <span class="nx">App</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span>
<span class="p">});</span>
</code></pre>
</div>
<h3>How should we lay out external scripts?</h3>
<p>Any modules we develop for our application using <span class="caps">AMD</span>/Require.js will be asynchronously loaded.</p>
<p>We have a heavy dependency on jQuery, Underscore and Backbone, unfortunatly this libraries are loaded synchronously and also depend on each other existing in the global namespace.</p>
<p>Below I propose a solution(until these libraries allow themselves to be loaded asynchronously) to allow these libraries to be loaded properly(synchronously) and also removing themselves from global scope.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: libs/jquery/jquery.js</span>

<span class="nx">define</span><span class="p">([</span>
<span class="c1">// Load the original jQuery source file</span>
  <span class="s1">&#39;order!libs/jquery/jquery-min&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(){</span>
  <span class="c1">// Tell Require.js that this module returns a reference to jQuery</span>
  <span class="k">return</span> <span class="nx">$</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: libs/underscore/underscore</span>
<span class="c1">// As above lets load the original underscore source code</span>
<span class="nx">define</span><span class="p">([</span><span class="s1">&#39;order!libs/underscore/underscore-min&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(){</span>
  <span class="c1">// Tell Require.js that this module returns  a reference to Underscore</span>
  <span class="k">return</span> <span class="nx">_</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<div class="highlight"><pre><code class="javascript"> <span class="c1">// Filename: libs/backbone/backbone</span>
 <span class="c1">// Finally lets load the original backbone source code</span>
<span class="nx">define</span><span class="p">([</span><span class="s1">&#39;order!libs/backbone/backbone-min&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(){</span>
  <span class="c1">// Now that all the orignal source codes have ran and accessed each other</span>
  <span class="c1">// We can call noConflict() to remove them from the global name space</span>
  <span class="c1">// Require.js will keep a reference to them so we can use them in our modules</span>
  <span class="nx">_</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span>
  <span class="nx">$</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span>
  <span class="k">return</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span>
<span class="p">});</span>
</code></pre>
</div>
<h3>A boiler plate module</h3>
<p>So before we start developing our application, let&#8217;s quickly look over boiler plate code that will be reused quite often.</p>
<p>For convience sake I generally keep a &#8220;boilerplate.js&#8221; in my application root so I can copy it when I need to.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">//Filename: boilerplate.js</span>

<span class="nx">define</span><span class="p">([</span>
  <span class="c1">// These are path alias that we configured in our bootstrap</span>
  <span class="s1">&#39;jQuery&#39;</span><span class="p">,</span>     <span class="c1">// lib/jquery/jquery</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span> <span class="c1">// lib/underscore/underscore</span>
  <span class="s1">&#39;Backbone&#39;</span>    <span class="c1">// lib/backbone/backbone</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">){</span>
  <span class="c1">// Above we have passed in jQuery, Underscore and Backbone</span>
  <span class="c1">// They will not be accesible in the global scope</span>
  <span class="k">return</span> <span class="p">{};</span>
  <span class="c1">// What we return here will be used by other modules	</span>
<span class="p">});</span>
</code></pre>
</div>
<p>The first argument of the define function is our dependency array, we can pass in any modules we like in the future.</p>
<h3>App.js Building our applications main module</h3>
<p>Our applications main module should always remain quite light weight.   This tutorial covers only setting up a Backbone Router and initializing it in our main module.</p>
<p>The router will then load the correct dependencies depending on the current <span class="caps">URL</span>.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: app.js</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;jQuery&#39;</span><span class="p">,</span> 
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span> 
  <span class="s1">&#39;Backbone&#39;</span><span class="p">,</span>
  <span class="s1">&#39;router&#39;</span><span class="p">,</span> <span class="c1">// Request router.js</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">Router</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">initialize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
    <span class="c1">// Pass in our Router module and call it&#39;s initialize function</span>
    <span class="nx">Router</span><span class="p">.</span><span class="nx">initialize</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="k">return</span> <span class="p">{</span> 
    <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span>
  <span class="p">};</span>
<span class="p">});</span>
</code></pre>
</div>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: router.js</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;jQuery&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Backbone&#39;</span><span class="p">,</span>
  <span class="s1">&#39;views/projects/list&#39;</span><span class="p">,</span>
  <span class="s1">&#39;views/users/list&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">Session</span><span class="p">,</span> <span class="nx">projectListView</span><span class="p">,</span> <span class="nx">userListView</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">AppRouter</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
    <span class="nx">routes</span><span class="o">:</span> <span class="p">{</span>
      <span class="c1">// Define some URL routes</span>
      <span class="s1">&#39;/projects&#39;</span><span class="o">:</span> <span class="s1">&#39;showProjects&#39;</span><span class="p">,</span>
      <span class="s1">&#39;/users&#39;</span><span class="o">:</span> <span class="s1">&#39;showUsers&#39;</span><span class="p">,</span>
      
      <span class="c1">// Default</span>
      <span class="s1">&#39;*actions&quot;: &quot;defaultAction&#39;</span>
    <span class="p">},</span>
    <span class="nx">showProjects</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
      <span class="c1">// Call render on the module we loaded in via the dependency array</span>
      <span class="c1">// &#39;views/projects/list&#39;</span>
      <span class="nx">projectListView</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span>
    <span class="p">},</span>
      <span class="c1">// As above, call render on our loaded module</span>
      <span class="c1">// &#39;views/users/list&#39;</span>
    <span class="nx">showUsers</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
      <span class="nx">userListView</span><span class="p">.</span><span class="nx">render</span><span class="p">();</span>
    <span class="p">},</span>
    <span class="nx">defaultAction</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">actions</span><span class="p">){</span>
      <span class="c1">// We have no matching route, lets just log what the URL was</span>
      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;No route:&#39;</span><span class="p">,</span> <span class="nx">actions</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">});</span>

  <span class="kd">var</span> <span class="nx">initialize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
    <span class="kd">var</span> <span class="nx">app_router</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">AppRouter</span><span class="p">;</span>
    <span class="nx">Backbone</span><span class="p">.</span><span class="nx">history</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
  <span class="p">};</span>
  <span class="k">return</span> <span class="p">{</span> 
    <span class="nx">initialize</span><span class="o">:</span> <span class="nx">initialize</span>
  <span class="p">};</span>
<span class="p">});</span>
</code></pre>
</div>
<h3>Modularizing a Backbone View</h3>
<p>Backbone views most usually always interact with the <span class="caps">DOM</span>, using our new modular system we can load in Javascript templates using Require.js text! plugin.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/project/list</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;jQuery&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Backbone&#39;</span><span class="p">,</span>
  <span class="c1">// Using the Require.js text! plugin, we are loaded raw text</span>
  <span class="c1">// which will be used as our views primary template</span>
  <span class="s1">&#39;text!templates/project/list.html&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">projectListTemplate</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">projectListView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
    <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#container&#39;</span><span class="p">),</span>
    <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
      <span class="c1">// Using Underscore we can compile our template with data</span>
      <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">{};</span>
      <span class="kd">var</span> <span class="nx">compiledTemplate</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">projectListTemplate</span><span class="p">,</span> <span class="nx">data</span> <span class="p">);</span>
      <span class="c1">// Append our compiled template to this Views &quot;el&quot;</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span> <span class="nx">compiledTemplate</span> <span class="p">);</span>
    <span class="p">}</span>
  <span class="p">});</span>
  <span class="c1">// Our module now returns an instantiated view</span>
  <span class="c1">// Sometimes you might return an un-instantiated view e.g. return projectListView</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nx">projectListView</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<p>Javascript templating allows us to seperate the design from the application logic placing all our html in the templates folder.</p>
<h3>Modularizing a Collection, Model and View</h3>
<p>Now we put it altogether by chaining up a Model, Collection and View which is a typical scenairo when building a Backbone.js application.</p>
<p>First off we will define our model</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: models/project</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Backbone&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">projectModel</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Model</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
    <span class="nx">defaults</span><span class="o">:</span> <span class="p">{</span>
      <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Harry Potter&quot;</span>
    <span class="p">}</span>
  <span class="p">});</span>
  <span class="c1">// You usually don&#39;t return a model instantiated</span>
  <span class="k">return</span> <span class="nx">projectModel</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<p>Now we have a model, our collection module can depend on it.  We will set the &#8220;model&#8221; attribute of our collection to the loaded module.  Backbone.js offers great benefits when doing this.</p>
<p>&#8220;Collection.model: Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to add, create, and reset, and the attributes will be converted into a model of the proper type.&#8221;</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: collections/projects</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Backbone&#39;</span><span class="p">,</span>
  <span class="c1">// Pull in the Model module from above</span>
  <span class="s1">&#39;models/project&#39;</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">projectModel</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">projectCollection</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">Collection</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
    <span class="nx">model</span><span class="o">:</span> <span class="nx">projectModel</span>
  <span class="p">});</span>
  <span class="c1">// You don&#39;t usually return a collection instantiated</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nx">projectCollection</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<p>Now we can simply depend on our collection in our view and pass it to our Javascript template.</p>
<div class="highlight"><pre><code class="javascript"><span class="c1">// Filename: views/projects/list</span>
<span class="nx">define</span><span class="p">([</span>
  <span class="s1">&#39;jQuery&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Underscore&#39;</span><span class="p">,</span>
  <span class="s1">&#39;Backbone&#39;</span><span class="p">,</span>
  <span class="c1">// Pull in the Collection module from above</span>
  <span class="s1">&#39;collections/projects&#39;</span><span class="p">,</span>
  <span class="err">&#39;</span><span class="nx">text</span><span class="o">!</span><span class="nx">templates</span><span class="o">/</span><span class="nx">projects</span><span class="o">/</span><span class="nx">list</span>
<span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">,</span> <span class="nx">projectsCollection</span><span class="p">,</span> <span class="nx">projectsListTemplate</span><span class="p">){</span>
  <span class="kd">var</span> <span class="nx">projectListView</span> <span class="o">=</span> <span class="nx">Backbone</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
    <span class="nx">el</span><span class="o">:</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#container&quot;</span><span class="p">),</span>
    <span class="nx">initialize</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">collection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">projectsCollection</span><span class="p">;</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">add</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Ginger Kid&quot;</span><span class="p">});</span>
      <span class="c1">// Compile the template using Underscores micro-templating</span>
      <span class="kd">var</span> <span class="nx">compiledTemplate</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span> <span class="nx">projectsListTemplate</span><span class="p">,</span> <span class="p">{</span> <span class="nx">projects</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">collection</span><span class="p">.</span><span class="nx">models</span> <span class="p">}</span> <span class="p">);</span>
      <span class="k">this</span><span class="p">.</span><span class="nx">el</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nx">compiledTemplate</span><span class="p">);</span> 
    <span class="p">}</span>
  <span class="p">});</span>
  <span class="c1">// Returning instantiated views can be quite useful for having &quot;state&quot;</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nx">projectListView</span><span class="p">;</span>
<span class="p">});</span>
</code></pre>
</div>
<h3>Conclusion</h3>
<p>Looking forward to feedback so I can turn this post and example into quality references on building modular Javascript applications.</p>
<p>Get in touch with me on twitter, comments or github!</p>
<h3>Relevant Links</h3>
<p><a href="http://weblog.bocoup.com/organizing-your-backbone-js-application-with-modules">Organizing Your Backbone.js Application With Modules</a></p>
<h3>Author</h3>
<ul>
	<li><a href="https://github.com/thomasdavis">Thomas Davis</a></li>
</ul>
<h3>Contributors</h3>
<ul>
	<li>None</li>
</ul>
</div>
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#pubid=xa-4db44541292b653d"></script>
<!-- AddThis Button END -->
<script>
var idcomments_acct = 'e6c0e0096f8106ea52c674a85b26ecf9';
var idcomments_post_id;
var idcomments_post_url = 'http://backbonetutorials.com/organizing-backbone-using-modules';
</script>
<span id="IDCommentsPostTitle" style="display:none"></span>
<script type='text/javascript' src='http://www.intensedebate.com/js/genericCommentWrapperV2.js'></script>
</div>

            


        </div>
      
    </div>
</div>
<script src="//static.getclicky.com/js" type="text/javascript"></script>
<script type="text/javascript">try{ clicky.init(66406579); }catch(e){}</script>
<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/66406579ns.gif" /></p></noscript>
</body>
</html>