~bac/juju-gui/trunkcopy

« back to all changes in this revision

Viewing changes to lib/yui/docs/app/index.html

  • Committer: kapil.foss at gmail
  • Date: 2012-07-13 18:45:59 UTC
  • Revision ID: kapil.foss@gmail.com-20120713184559-2xl7be17egsrz0c9
reshape

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!DOCTYPE html>
2
 
<html lang="en">
3
 
<head>
4
 
    <meta charset="utf-8">
5
 
    <title>App Framework</title>
6
 
    <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Maven+Pro:400,700">
7
 
    <link rel="stylesheet" href="../../build/cssgrids/grids-min.css">
8
 
    <link rel="stylesheet" href="../assets/css/main.css">
9
 
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
10
 
    <script src="../../build/yui/yui-min.js"></script>
11
 
</head>
12
 
<body>
13
 
 
14
 
<div id="doc">
15
 
    <h1>App Framework</h1>
16
 
 
17
 
    
18
 
        <a href="#toc" class="jump">Jump to Table of Contents</a>
19
 
    
20
 
 
21
 
    <div class="yui3-g">
22
 
        <div class="yui3-u-3-4">
23
 
            <div id="main">
24
 
                <div class="content"><div class="intro">
25
 
<p>
26
 
The YUI App Framework is a rollup of the <a href="#app-component">App</a>, <a href="../model/index.html">Model</a>, <a href="../model-list/index.html">Model List</a>, <a href="../router/index.html">Router</a>, and <a href="../view/index.html">View</a> components, combined to form a simple MVC-style framework for writing single-page JavaScript applications.
27
 
</p>
28
 
 
29
 
<p>
30
 
You can use these components separately or together to create anything from simple non-interactive views to rich applications with URL-based routing, data binding, and full client-server synchronization.
31
 
</p>
32
 
 
33
 
<p>
34
 
If you've used <a href="http://www.documentcloud.org/">DocumentCloud</a>'s excellent <a href="http://documentcloud.github.com/backbone/">Backbone.js</a> framework, many of the classes and APIs provided by App Framework components will look familiar to you. There are important differences, though, and the App Framework takes full advantage of YUI's powerful component and event infrastructure under the hood.
35
 
</p>
36
 
</div>
37
 
 
38
 
<h2 id="getting-started">Getting Started</h2>
39
 
 
40
 
<p>
41
 
To include the source files for App Framework and its dependencies, first load
42
 
the YUI seed file if you haven't already loaded it.
43
 
</p>
44
 
 
45
 
<pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.5.1&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>
46
 
 
47
 
 
48
 
<p>
49
 
Next, create a new YUI instance for your application and populate it with the
50
 
modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
51
 
YUI will automatically load any dependencies required by the modules you
52
 
specify.
53
 
</p>
54
 
 
55
 
<pre class="code prettyprint">&lt;script&gt;
56
 
&#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
57
 
YUI().use(&#x27;app&#x27;, function (Y) {
58
 
    &#x2F;&#x2F; App Framework is available and ready for use. Add implementation
59
 
    &#x2F;&#x2F; code here.
60
 
});
61
 
&lt;&#x2F;script&gt;</pre>
62
 
 
63
 
 
64
 
<p>
65
 
For more information on creating YUI instances and on the
66
 
<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
67
 
documentation for the <a href="../yui/index.html">YUI Global Object</a>.
68
 
</p>
69
 
 
70
 
 
71
 
<h2 id="components-of-the-app-framework">Components of the App Framework</h2>
72
 
 
73
 
<p>
74
 
The <code>app</code> module is a rollup module consisting of the following individual components. These components may also be used individually if you don't need all of them at the same time.
75
 
</p>
76
 
 
77
 
<table>
78
 
  <thead>
79
 
    <tr>
80
 
      <th>Component</th>
81
 
      <th>Module</th>
82
 
      <th>Description</th>
83
 
    </tr>
84
 
  </thead>
85
 
  <tbody>
86
 
    <tr>
87
 
      <td><a href="#app-component">App</a></td>
88
 
      <td style="white-space: nowrap;"><code>app-base</code></td>
89
 
      <td>
90
 
        <p>
91
 
        Provides a top-level application component which manages navigation and views. This gives you a foundation and structure on which to build your application; it combines robust URL navigation with powerful routing and flexible view management.
92
 
        </p>
93
 
      </td>
94
 
    </tr>
95
 
 
96
 
    <tr>
97
 
      <td><a href="../model/index.html">Model</a></td>
98
 
      <td><code>model</code></td>
99
 
      <td>
100
 
        <p>
101
 
        A lightweight <a href="http://yuilibrary.com/yui/docs/api/classes/Attribute.html"><code>Y.Attribute</code></a>-based data model with APIs for getting, setting, validating, and syncing attribute values to a persistence layer or server, as well as events for notifying subscribers of model changes.
102
 
        </p>
103
 
      </td>
104
 
    </tr>
105
 
 
106
 
    <tr>
107
 
      <td><a href="../model-list/index.html">Model List</a></td>
108
 
      <td style="white-space: nowrap;"><code>model-list</code></td>
109
 
      <td>
110
 
        <p>
111
 
        An array-like ordered list of <code>Y.Model</code> instances with APIs for adding, removing, sorting, filtering, and performing other actions on models in the list. Acts as a bubble target for events fired by the models in the list.
112
 
        </p>
113
 
      </td>
114
 
    </tr>
115
 
 
116
 
    <tr>
117
 
      <td><a href="../router/index.html">Router</a></td>
118
 
      <td><code>router</code></td>
119
 
      <td>
120
 
        <p>
121
 
        Provides URL-based same-page routing using <a href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history">HTML5 history</a> (<code>pushState</code>) or the location hash, depending on what the user's browser supports.
122
 
        </p>
123
 
      </td>
124
 
    </tr>
125
 
 
126
 
    <tr>
127
 
      <td><a href="../view/index.html">View</a></td>
128
 
      <td><code>view</code></td>
129
 
      <td>
130
 
        <p>
131
 
        Represents a piece of an application's user interface and is responsible for rendering content and handling DOM events. Views are commonly associated with Models or Model Lists and are re-rendered when they change, although this isn't required.
132
 
        </p>
133
 
      </td>
134
 
    </tr>
135
 
  </tbody>
136
 
</table>
137
 
 
138
 
<h2 id="app-component">App Component</h2>
139
 
 
140
 
<p>
141
 
App is a high-level component that builds upon other components in the App Framework. The App component is composed of <a href="../router/index.html">Router</a> and <a href="../view/index.html">View</a>, and also the <a href="../pjax/index.html">Pjax</a> utility. This combination creates a solid foundation and structure on which to build your application. It connects together robust URL navigation with powerful routing and flexible view management.
142
 
</p>
143
 
 
144
 
<p>
145
 
The goal of the App component is to provide you a place to organize and connect together the parts of your application. App implements infrastructural pieces which are common to all apps â€” such as <a href="#view-management">managing views</a> and the <a href="#navigating-between-pages">navigation between pages</a> â€” allowing you to focus on the specifics of <em>your</em> app.
146
 
</p>
147
 
 
148
 
<p>
149
 
App will enable you to seamlessly enhance the user experience and performance of traditional client/server apps. It enables you to create richer interactions without compromising standard browser behavior, URLs, or search engine craw-ability. The <a href="#routing-coordination-with-server">Routing Coordination with Server</a> section of this guide contain details on accomplishing this.
150
 
</p>
151
 
 
152
 
<p>
153
 
You can also use the App component to build client-only apps for when there is no server, or the server is not capable of routing and handling requests. There are <strong>drawbacks to client-only apps</strong> which you need to be aware of and fully understand their implications. Be sure to read the <a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a> section which contains details on these drawbacks and best practices.
154
 
</p>
155
 
 
156
 
<p>
157
 
The remaining sections of this guide provide details on what you'll need to know to start working with the App component. Refer to the previous section for information about the <a href="#components-of-the-app-framework">other components of the App Framework</a>.
158
 
</p>
159
 
 
160
 
<h2 id="using-app">Using App</h2>
161
 
 
162
 
<h3 id="instantiating-app">Instantiating App</h3>
163
 
 
164
 
<p>
165
 
Creating an App instance couldn't be any simpler:
166
 
</p>
167
 
 
168
 
<pre class="code prettyprint">var app = new Y.App();</pre>
169
 
 
170
 
 
171
 
<p>
172
 
Two instantiable classes are provided by the <code>app-base</code> module: <code>Y.App</code>, and <code>Y.App.Base</code>. The difference between these is that <code>Y.App.Base</code> provides the basic app functionality and will remain pure; whereas <code>Y.App</code> (which extends <code>Y.App.Base</code>) will have all of the app-component extensions automatically mixed-in when they are included in the YUI instance.
173
 
</p>
174
 
 
175
 
<p>
176
 
In the following example, we are including both the <code>app-base</code> and <code>app-transitions</code> modules. When the <code>app-transitions</code> module is added to the YUI instance it will automatically mix itself into the <code>Y.App</code> class, adding transitions to all <code>Y.App</code> instances, but <code>Y.App.Base</code> will remain unaffected by the inclusion of this module.
177
 
</p>
178
 
 
179
 
<pre class="code prettyprint">YUI().use(&#x27;app-base&#x27;, &#x27;app-transitions&#x27;, function (Y) {
180
 
    &#x2F;&#x2F; This will create two YUI Apps, &#x60;basicApp&#x60; will not have transitions,
181
 
    &#x2F;&#x2F; but &#x60;fancyApp&#x60; will have transitions support included and turn itself on.
182
 
    var basicApp = new Y.App.Base(),
183
 
        fancyApp = new Y.App({transitions: true});
184
 
});</pre>
185
 
 
186
 
 
187
 
<p>
188
 
While App instances are usable without any configuration, any non-trivial app will need to be configured. You might also want to extend <code>Y.App</code> by mixing-in additional functionality, or even create a custom App class to implement the specific features of your application. The <a href="#extending-yapp">Extending <code>Y.App</code></a> section explains how to do this.
189
 
</p>
190
 
 
191
 
<h4 id="config-properties">Config Properties</h4>
192
 
 
193
 
<p>
194
 
When constructing a new <code>Y.App</code> instance you can provide a config object with initial values for <a href="#app-attributes">attributes</a> along with values for <a href="../view/index.html#view-properties"><code>Y.View</code>'s properties</a> and <a href="../api/classes/Base.html"><code>Y.Base</code>'s "special" properties</a> (used only during initialization). In addition to these, the following non-attribute properties have specific initialization logic applied and can be passed to the <code>Y.App</code> constructor:
195
 
</p>
196
 
 
197
 
<dl>
198
 
  <dt><code>views</code></dt>
199
 
  <dd>
200
 
    <p>
201
 
    Hash of view-name to metadata used to declaratively describe an application's views and their relationship with the app and its other views. The views specified here will override any defaults provided by the <code>views</code> object on the <code>prototype</code>. Every <code>Y.App</code> instance gets its own copy of a <code>views</code> object so this object on the prototype will not be polluted.
202
 
    </p>
203
 
 
204
 
    <p>
205
 
    See the <a href="#app-properties">App Properties</a> and <a href="#declaring-views">Declaring Views</a> sections for more details.
206
 
    </p>
207
 
  </dd>
208
 
</dl>
209
 
 
210
 
<p>
211
 
Here's an example that defines some <code>views</code> at instantiation time:
212
 
</p>
213
 
 
214
 
<pre class="code prettyprint">var app = new Y.App({
215
 
    views: {
216
 
        home : {preserve: true},
217
 
        users: {preserve: true},
218
 
        user : {parent: &#x27;users&#x27;}
219
 
    }
220
 
});</pre>
221
 
 
222
 
 
223
 
<h3 id="app-properties">App Properties</h3>
224
 
 
225
 
<p>
226
 
The following properties are meaningful to App classes and subclasses. In addition to these, <a href="../view/index.html#view-properties">View's properties</a> are also applicable <code>Y.View</code> is part of App's composition.
227
 
</p>
228
 
 
229
 
<table>
230
 
  <thead>
231
 
    <tr>
232
 
      <th>Property</th>
233
 
      <th>Default Value</th>
234
 
      <th>Description</th>
235
 
    </tr>
236
 
  </thead>
237
 
  <tbody>
238
 
    <tr>
239
 
      <td><code>views</code></td>
240
 
      <td><code>{}</code></td>
241
 
      <td>
242
 
        <p>
243
 
        Hash of view-name to metadata used to declaratively describe an application's views and their relationship with the app and its other views. See <a href="#declaring-views">Declaring Views</a> for more details.
244
 
        </p>
245
 
 
246
 
        <p>
247
 
        The view metadata is composed of Objects keyed to a view-name that can have any or all of the following properties:
248
 
        </p>
249
 
 
250
 
        <dl style="margin-top:1em">
251
 
          <dt><code>type</code></dt>
252
 
          <dd>
253
 
            <p>
254
 
            Function or a string representing the view constructor to use to create view instances. If a string is used, the constructor function is assumed to be on the <code>Y</code> object; e.g. <code>&quot;SomeView&quot;</code> -> <code>Y.SomeView</code>.
255
 
            </p>
256
 
          </dd>
257
 
 
258
 
          <dt><code>preserve</code></dt>
259
 
          <dd>
260
 
            <p>
261
 
            Boolean for whether the view instance should be retained. By default, the view instance will be destroyed when it is no longer the <code>activeView</code>. If <code>true</code> the view instance will simply be <code>removed()</code> from the DOM when it is no longer active. This is useful when the view is frequently used and may be expensive to re-create. See <a href="#preserved-views">Preserved Views</a> for best practices.
262
 
            </p>
263
 
          </dd>
264
 
 
265
 
          <dt><code>parent</code></dt>
266
 
          <dd>
267
 
            <p>
268
 
            String to another named view in this hash that represents the parent view within the application's view hierarchy; e.g. a <code>&quot;photo&quot;</code> view could have <code>&quot;album&quot;</code> has its <code>parent</code> view. This parent/child relationship is a useful cue for things like transitions.
269
 
            </p>
270
 
          </dd>
271
 
 
272
 
          <dt><code>instance</code></dt>
273
 
          <dd>
274
 
            <p>
275
 
            Used internally to manage the current instance of this named view. This can be used if your view instance is created up-front, or if you would rather manage the View lifecycle, but you probably should just let this be handled for you.
276
 
            </p>
277
 
          </dd>
278
 
        </dl>
279
 
      </td>
280
 
    </tr>
281
 
 
282
 
    <tr>
283
 
      <td><code>transitions</code></td>
284
 
      <td><code>{}</code></td>
285
 
      <td>
286
 
        <p>
287
 
        Default transitions to use when the <code>activeView</code> changes. See the <a href="#switching-the-active-view">Switching the Active View</a> and <code><a href="#yapptransitions">Y.App.Transitions</a></code> sections for more details.
288
 
        </p>
289
 
 
290
 
        <p>
291
 
        The following are types of changes for which transitions can be defined that correspond to the relationship between the new and old <code>activeView</code>:
292
 
        </p>
293
 
 
294
 
        <dl style="margin-top:1em">
295
 
          <dt><code>navigate</code></dt>
296
 
          <dd>
297
 
            <p>
298
 
            The default transition to use when changing the <code>activeView</code> of the application. This will be <strong><code>&quot;fade&quot;</code></strong> by default.
299
 
            </p>
300
 
          </dd>
301
 
 
302
 
          <dt><code>toChild</code></dt>
303
 
          <dd>
304
 
            <p>
305
 
            The transition to use when the new <code>activeView</code> is configured as a child of the previously active view via its <code>parent</code> property as defined in this app's <code>views</code>. This will be <strong><code>&quot;slideLeft&quot;</code></strong> by default.
306
 
            </p>
307
 
          </dd>
308
 
 
309
 
          <dt><code>toParent</code></dt>
310
 
          <dd>
311
 
            <p>
312
 
            The transition to use when the new <code>activeView</code> is configured as the <code>parent</code> of the previously active view as defined in this app's <code>views</code>. This will be <strong><code>&quot;slideRight&quot;</code></strong> by default.
313
 
            </p>
314
 
          </dd>
315
 
        </dl>
316
 
      </td>
317
 
    </tr>
318
 
  </tbody>
319
 
</table>
320
 
 
321
 
<p>
322
 
The App class uses both properties and attributes. Properties are best when their stored data might be useful to multiple App instances, whereas attributes are best when the data being stored only pertains to a single instance.
323
 
</p>
324
 
 
325
 
<h3 id="app-attributes">App Attributes</h3>
326
 
 
327
 
<p>
328
 
App is composed of <a href="../view/index.html#view-attributes">View</a>, <a href="../router/index.html#config-attributes">Router</a>, and <a href="../pjax/index.html#config-attributes">Pjax</a>, all of which provide attributes that will be of interest to you â€” beyond these, App adds the following attributes:
329
 
</p>
330
 
 
331
 
<table>
332
 
  <thead>
333
 
    <tr>
334
 
      <th>Attribute</th>
335
 
      <th>Default Value</th>
336
 
      <th>Description</th>
337
 
    </tr>
338
 
  </thead>
339
 
  <tbody>
340
 
    <tr>
341
 
      <td><code>activeView</code></td>
342
 
      <td><code>null</code></td>
343
 
      <td>
344
 
        <p>
345
 
        The application's active/visible view. This attribute is read-only, to set the <code>activeView</code> use the <code>showView()</code> method.
346
 
        </p>
347
 
 
348
 
        <p>
349
 
        See <a href="#switching-the-active-view">Switching the Active View</a> for more details.
350
 
        </p>
351
 
      </td>
352
 
    </tr>
353
 
 
354
 
    <tr>
355
 
      <td><code>serverRouting</code></td>
356
 
      <td><code>undefined</code></td>
357
 
      <td>
358
 
        <p>
359
 
        Whether or not this application's server is capable of properly routing all requests and rendering the initial state in the HTML responses.
360
 
        </p>
361
 
 
362
 
        <p>
363
 
        This can have three different values, each having particular implications on how the app will handle routing and navigation:
364
 
        </p>
365
 
 
366
 
        <dl style="margin-top:1em">
367
 
          <dt><code>undefined</code></dt>
368
 
          <dd>
369
 
            <p>
370
 
            The best form of URLs will be chosen based on the capabilities of the browser. Given no information about the server environment, a balanced approach to routing and navigation is chosen. See <a href="#urls-based-on-browser-capabilities">URLs Based on Browser Capabilities</a> for more details.
371
 
            </p>
372
 
          </dd>
373
 
 
374
 
          <dt><code>true</code></dt>
375
 
          <dd>
376
 
            <p>
377
 
            The server is <em>fully</em> capable of properly handling requests to all full-path URLs the app can produce.
378
 
            </p>
379
 
 
380
 
            <p>
381
 
            This is the best option for progressive-enhancement because it will cause <strong>all URLs to always have full-paths</strong>, which means the server will be able to accurately handle all URLs this app produces. See <a href="#full-path-urls-only">Full-path URLs Only</a> and <a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a> for more details.
382
 
            </p>
383
 
          </dd>
384
 
 
385
 
          <dt><code>false</code></dt>
386
 
          <dd>
387
 
            <p>
388
 
            The server is <em>not</em> capable of properly handling requests to all full-path URLs the app can produce, therefore <em>all</em> routing will be handled by this App instance.
389
 
            </p>
390
 
 
391
 
            <p>
392
 
            Be aware that this will cause <strong>all URLs to always be hash-based</strong>, even in browsers that are capable of using HTML5 history. Please make sure you fully understand the implications of client-only apps. See <a href="#hash-based-urls-only">Hash-based URLs Only</a> and <a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a> for more details.
393
 
            </p>
394
 
          </dd>
395
 
        </dl>
396
 
 
397
 
        <p>
398
 
        See <a href="#routing-coordination-with-server">Routing Coordination with Server</a> for more details.
399
 
        </p>
400
 
      </td>
401
 
    </tr>
402
 
 
403
 
    <tr>
404
 
      <td><code>transitions</code></td>
405
 
      <td><code>false</code></td>
406
 
      <td>
407
 
        <p>
408
 
        Whether or not this application should use view transitions, and if so then which ones or <code>true</code> for the defaults which are specified by the <code>transitions</code> prototype property.
409
 
        </p>
410
 
 
411
 
        <p>
412
 
        <strong>Note:</strong> Transitions are an opt-in feature and will only be used in browsers which support native CSS3 transitions.
413
 
        </p>
414
 
 
415
 
        <p>
416
 
        See the <a href="#switching-the-active-view">Switching the Active View</a> and <code><a href="#yapptransitions">Y.App.Transitions</a></code> sections for more details.
417
 
        </p>
418
 
      </td>
419
 
    </tr>
420
 
 
421
 
    <tr>
422
 
      <td><code>viewContainer</code></td>
423
 
      <td><code>&lt;div&gt;</code> Node</td>
424
 
      <td>
425
 
        <p>
426
 
        The node into which this app's <code>views</code> will be rendered when they become the <code>activeView</code>.
427
 
        </p>
428
 
 
429
 
        <p>
430
 
        The view container node serves as the container to hold the app's <code>activeView</code>. Each time the <code>activeView</code> is set via <code>showView()</code>, the previous view will be removed from this node, and the new active view's <code>container</code> node will be appended.
431
 
        </p>
432
 
 
433
 
        <p>
434
 
        The default view container is a <code>&lt;div&gt;</code> Node, but you can override this in a subclass, or by passing in a custom <code>viewContainer</code> config value at instantiation time. The <code>viewContainer</code> may be provided as a selector string, DOM element, or a <code>Y.Node</code> instance (having the <code>viewContainer</code> and the <code>container</code> be the same node is also supported).
435
 
        </p>
436
 
 
437
 
        <p>
438
 
        The app's <code>render()</code> method will stamp the view container with the CSS class <code>&quot;yui3-app-views&quot;</code> and append it to the app's <code>container</code> node if it isn't already, and any <code>activeView</code> will be appended to this node if it isn't already.
439
 
        </p>
440
 
 
441
 
        <p>
442
 
        See <a href="#rendering-an-app">Rendering an App</a> for more details.
443
 
        </p>
444
 
      </td>
445
 
    </tr>
446
 
  </tbody>
447
 
</table>
448
 
 
449
 
<p>
450
 
A few of App's inherited attributes are given new default values:
451
 
</p>
452
 
 
453
 
<table>
454
 
  <thead>
455
 
    <tr>
456
 
      <th>Attribute</th>
457
 
      <th>Inherited From</th>
458
 
      <th>New Default Value</th>
459
 
      <th>Reason</th>
460
 
    </tr>
461
 
  </thead>
462
 
  <tbody>
463
 
    <tr>
464
 
      <td><code>container</code></td>
465
 
      <td><code>Y.View</code></td>
466
 
      <td><code>&lt;body&gt;</code> Node</td>
467
 
      <td>
468
 
        <p>
469
 
        Apps are considered to be full-page by default.
470
 
        </p>
471
 
      </td>
472
 
    </tr>
473
 
 
474
 
    <tr>
475
 
      <td><code>html5</code></td>
476
 
      <td><code>Y.Router</code></td>
477
 
      <td>auto</td>
478
 
      <td>
479
 
        <p>
480
 
        This value is dependent on the value of <code>serverRouting</code> and will default accordingly.
481
 
        </p>
482
 
      </td>
483
 
    </tr>
484
 
 
485
 
    <tr>
486
 
      <td><code>linkSelector</code></td>
487
 
      <td><code>Y.PjaxBase</code></td>
488
 
      <td><code>&quot;a&quot;</code></td>
489
 
      <td>
490
 
        <p>
491
 
        By default this selector should match <em>all</em> links on the page because full-page apps are the default.
492
 
        </p>
493
 
      </td>
494
 
    </tr>
495
 
  </tbody>
496
 
</table>
497
 
 
498
 
<h3 id="routing-coordination-with-server">Routing Coordination with Server</h3>
499
 
 
500
 
<p>
501
 
A primary feature of App is its powerful routing which enables you to enhance the user experience and performance of traditional client/server apps. Using <code>Y.App</code> you can create more meaningful and richer interactions for a user navigating through your application. App's routing features center on progressive enhancement and do <em>not</em> compromise standard browser features (back/forward button support), URLs, or search engine craw-ability.
502
 
</p>
503
 
 
504
 
<p>
505
 
There are two attributes which are used to configure an app's URLs and how its routing should coordinate with the server:
506
 
</p>
507
 
 
508
 
<dl>
509
 
  <dt><code>root</code></dt>
510
 
  <dd>
511
 
    <p>
512
 
    An app's <code>root</code> is the absolute path from which all routes should be evaluated, i.e. the path at which the app is mounted, usually "/".
513
 
    </p>
514
 
 
515
 
    <p>
516
 
    See <a href="../router/index.html#setting-the-root-path">Setting the Root Path</a> in Router's user guide for more information.
517
 
    </p>
518
 
  </dd>
519
 
 
520
 
  <dt><code>serverRouting</code></dt>
521
 
  <dd>
522
 
    <p>
523
 
    Models a higher level concept over the capabilities of, and interactions between the browser and server with respect to URLs and inter-page navigation. This attribute determines how your <code>Y.App</code> instance will interact with the server: set this to <code>true</code> if the app can be progressively enhanced, or <code>false</code> if it's a client side-only app.
524
 
    </p>
525
 
 
526
 
    <p>
527
 
    <strong>Note:</strong> The value of an app's <code>html5</code> attribute depends on the value of its <code>serverRouting</code> attribute. When <code>serverRouting</code> is explicit set to <code>false</code> (not just falsy), the default value for <code>html5</code> will be set to <code>false</code> for <em>all</em> browsers. When <code>serverRouting</code> is <code>true</code> or <code>undefined</code> the returned value will be dependent on the browser's capability of using HTML5 history.
528
 
    </p>
529
 
  </dd>
530
 
</dl>
531
 
 
532
 
<p>
533
 
<strong>Looking for general information about routing?</strong> See the <a href="../router/index.html#routing">Routing</a> section in Router's user guide.
534
 
</p>
535
 
 
536
 
<h4 id="urls-based-on-browser-capabilities">URLs Based on Browser Capabilities</h4>
537
 
 
538
 
<p>
539
 
This is the <strong>default</strong> behavior of how an app's routing will coordinate with the server. When <code>serverRouting</code> is left <code>undefined</code>, the app is given no information about the server's capabilities. In this case a balanced approach to URLs, routing, and navigation will be used:
540
 
</p>
541
 
 
542
 
<ul>
543
 
  <li>
544
 
    <p>
545
 
    Full-path URLs will only be used if the browser is capable of using HTML5 history, otherwise hash-based URLs will be used.
546
 
    </p>
547
 
  </li>
548
 
 
549
 
  <li>
550
 
    <p>
551
 
    The <code>Y.App</code> instance will handle <em>all</em> routing since it is unknown whether the server is capable of properly routing requests.
552
 
    </p>
553
 
  </li>
554
 
 
555
 
  <li>
556
 
    <p>
557
 
    The server is <em>required</em> to handle full-path URLs which will be generated by browsers which use the HTML5 <code>pushState()</code> history API. A server can handle these requests by either rendering the initial state in the HTML, or redirecting to a hash-based URL and letting the app dispatch to its route handlers.
558
 
    </p>
559
 
  </li>
560
 
</ul>
561
 
 
562
 
<p>
563
 
This behavior has been chosen as the default because it provides the best path forward for a developer to upgrade a client side-only app to a progressively enhanced app (but you should always prefer to build an app using progressive enhancement from the start, that's the whole point).
564
 
</p>
565
 
 
566
 
<p>
567
 
The following is a simple <a href="http://nodejs.org/">Node.js</a> <a href="http://expressjs.com/">Express</a> server and very basic <code>Y.App</code> instance which demonstrate how the client and server can coordinate routing and the fulfillment of a request when using URLs that conform to the capabilities of the browser, but the server is "dumb":
568
 
</p>
569
 
 
570
 
<h5 class="no-toc">server.js - The Node.js Express server</h5>
571
 
 
572
 
<pre class="code prettyprint">var server = require(&#x27;express&#x27;).createServer();
573
 
 
574
 
&#x2F;&#x2F; Handles requests to the root path (&quot;&#x2F;&quot;) my simply sending the &quot;shell&quot; page
575
 
&#x2F;&#x2F; which creates the &#x60;Y.App&#x60; instance.
576
 
server.get(&#x27;&#x2F;&#x27;, function (req, res) {
577
 
    res.sendfile(&#x27;index.html&#x27;);
578
 
});
579
 
 
580
 
&#x2F;&#x2F; Handles all other requests by redirecting the browser back to the root path
581
 
&#x2F;&#x2F; and tacking on URL&#x27;s path as the fragment; e.g. &quot;&#x2F;foo&#x2F;&quot; =&gt; &quot;&#x2F;#&#x2F;foo&#x2F;&quot;.
582
 
server.get(&#x27;*&#x27;, function (req, res) {
583
 
    res.redirect(&#x27;&#x2F;#&#x27; + req.url, 302);
584
 
});
585
 
 
586
 
server.listen(process.env.PORT || 3000);</pre>
587
 
 
588
 
 
589
 
<h5 class="no-toc"><code>index.html</code> - The "shell" page for the <code>Y.App</code> instance</h5>
590
 
 
591
 
<pre class="code prettyprint">&lt;!DOCTYPE html&gt;
592
 
 
593
 
&lt;html&gt;
594
 
&lt;head&gt;
595
 
    &lt;meta charset=&quot;utf-8&quot; &#x2F;&gt;
596
 
    &lt;title&gt;Example App&lt;&#x2F;title&gt;
597
 
&lt;&#x2F;head&gt;
598
 
&lt;body&gt;
599
 
 
600
 
    &lt;h1&gt;&lt;&#x2F;h1&gt;
601
 
 
602
 
    &lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.5.1&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;
603
 
    &lt;script&gt;
604
 
    YUI().use(&#x27;app-base&#x27;, function (Y) {
605
 
 
606
 
        var app = new Y.App({
607
 
            &#x2F;&#x2F; Configure the app.
608
 
        });
609
 
 
610
 
        &#x2F;&#x2F; Handles requests for the root by updating the page heading.
611
 
        app.route(&#x27;&#x2F;&#x27;, function () {
612
 
            Y.one(&#x27;h1&#x27;).set(&#x27;text&#x27;, &#x27;Example App - Home&#x27;);
613
 
        });
614
 
 
615
 
        &#x2F;&#x2F; Handles all other requests by updating the page heading and
616
 
        &#x2F;&#x2F; displaying current path in it.
617
 
        app.route(&#x27;*&#x27;, function (req) {
618
 
            Y.one(&#x27;h1&#x27;).set(&#x27;text&#x27;, &#x27;Example App - &#x27; + req.path);
619
 
        });
620
 
 
621
 
        &#x2F;&#x2F; Make sure to dispatch the current hash-based URL which was set by
622
 
        &#x2F;&#x2F; the server to our route handlers.
623
 
        app.render().dispatch();
624
 
 
625
 
    });
626
 
    &lt;&#x2F;script&gt;
627
 
 
628
 
&lt;&#x2F;body&gt;
629
 
&lt;&#x2F;html&gt;</pre>
630
 
 
631
 
 
632
 
<p>
633
 
In the above example, the server handles full URLs by sending a redirect back to the root ("/") with a hash-based path and serves a "shell" HTML page to delegate control to a <code>Y.App</code> instance. Once the app is loaded, it will dipatch the hash-based path to its route handlers, finishing the fulfillment of the request on the client.
634
 
</p>
635
 
 
636
 
<p>
637
 
You could also implement the server-side redirection logic using an Apache Mod Rewrite <code>.htaccess</code> file:
638
 
</p>
639
 
 
640
 
<pre class="code">RewriteEngine On
641
 
RewriteRule ^(.+)$ &#x2F;#&#x2F;$1 [L]</pre>
642
 
 
643
 
 
644
 
<h4 id="full-path-urls-only">Full-path URLs Only</h4>
645
 
 
646
 
<p>
647
 
Full-path URLs are standard URLs which have matching routes based on the URL's path segments. The follow are example full-path URLs you might expect to see in a photos application:
648
 
</p>
649
 
 
650
 
<pre class="code">http:&#x2F;&#x2F;example.com&#x2F;
651
 
http:&#x2F;&#x2F;example.com&#x2F;photos&#x2F;
652
 
http:&#x2F;&#x2F;example.com&#x2F;photos&#x2F;1
653
 
http:&#x2F;&#x2F;example.com&#x2F;photos&#x2F;2
654
 
http:&#x2F;&#x2F;example.com&#x2F;albums&#x2F;
655
 
http:&#x2F;&#x2F;example.com&#x2F;albums&#x2F;vacation</pre>
656
 
 
657
 
 
658
 
<p>
659
 
Setting an app's <code>serverRouting</code> attribute to <code>true</code> signals that the server <em>is</em> capable of properly handling requests to all full-path URLs the app can produce. This causes the app to <em>always</em> use full-path URLs, regardless of whether the browser can use HTML5 history or not. In this case the capabilities of the client and server are coordinated in the most optimal way, giving the app the following qualities:
660
 
</p>
661
 
 
662
 
<ul>
663
 
  <li>
664
 
    <p>
665
 
    Full-path URLs are <em>always</em> used, older browsers which can not use HTML5 history will have to do full page loads.
666
 
    </p>
667
 
  </li>
668
 
 
669
 
  <li>
670
 
    <p>
671
 
    The <code>Y.App</code> instance will only handle routing in browser which support HTML5 history, the other browser's "requests" will be handled completely by the server.
672
 
    </p>
673
 
  </li>
674
 
 
675
 
  <li>
676
 
    <p>
677
 
    The server is <em>required</em> to handle full-path URLs which will be generated by the app. Ideally the server should render the application's initial state in the response HTML for the given URL.
678
 
    </p>
679
 
  </li>
680
 
</ul>
681
 
 
682
 
<p>
683
 
This is the <strong>best option for progressive enhancement</strong>! All users of your app will have the same, full-path URLs, independent of the browser or device they are using. Configuring your app with <code>serverRouting</code> set to <code>true</code> means that the client and server components of your application are working together to provide the best overall experience for your users.
684
 
</p>
685
 
 
686
 
<p>
687
 
See <a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a> for more information about best practices.
688
 
</p>
689
 
 
690
 
<h4 id="hash-based-urls-only">Hash-based URLs Only</h4>
691
 
 
692
 
<p>
693
 
Hash-based URLs have matching routes based on the URL's fragment identifier ("#"). The follow are example hash-based URLs you might expect to see in a photos application:
694
 
</p>
695
 
 
696
 
<pre class="code">http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;
697
 
http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;photos&#x2F;
698
 
http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;photos&#x2F;1
699
 
http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;photos&#x2F;2
700
 
http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;albums&#x2F;
701
 
http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;albums&#x2F;vacation</pre>
702
 
 
703
 
 
704
 
<p>
705
 
Notice how the above URLs actually all contain the same path segment ("/"), but use the fragment identifier ("#") to hold a pseudo-path value.
706
 
</p>
707
 
 
708
 
<p>
709
 
Setting an app's <code>serverRouting</code> attribute to <code>false</code> signals that the server is <em>not</em> capable of properly handling requests to full-path URLs. This causes the app to <em>always</em> use hash-based URLs, regardless of the browser's capabilities. In this case the app will assume that there is no server to rely on, giving the app the following qualities:
710
 
</p>
711
 
 
712
 
<ul>
713
 
  <li>
714
 
    <p>
715
 
    Be aware that <strong>all URLs will be hash-based</strong>, even in browsers which are capable of using HTML5 history.
716
 
    </p>
717
 
  </li>
718
 
 
719
 
  <li>
720
 
    <p>
721
 
    The <code>Y.App</code> instance will handle all routing since there is no server capable of properly routing handling requests.
722
 
    </p>
723
 
  </li>
724
 
 
725
 
  <li>
726
 
    <p>
727
 
    The server is only expected to serve out a static HTML "shell" page with the required JavaScript to instantiate the <code>Y.App</code> instance, which will then render the initial state of the application.
728
 
    </p>
729
 
  </li>
730
 
</ul>
731
 
 
732
 
<p>
733
 
This is the best option if there is no guarantee that your app will be served by a capable server. This allows an app to run when hosted on the filesystem or static file server. You should be aware that using hash-based URLs means there will be information loss. The server will <em>not</em> receive the full URL because browsers do not send the fragment-part to the server, that is everything after and including the "#".
734
 
</p>
735
 
 
736
 
<p>
737
 
<strong>Please read</strong> <a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a> for more information and best practices.
738
 
</p>
739
 
 
740
 
<h3 id="rendering-an-app">Rendering an App</h3>
741
 
 
742
 
<p>
743
 
App inherits both its <code>container</code> attribute and <code>render()</code> method from View. Unlike <a href="../view/index.html#rendering-a-view">View's empty <code>render()</code> implementation</a>, App provides a default implementation which appends the <code>activeView</code> (if there is one) to the <code>viewContainer</code> node which itself is appended to the <code>container</code> node.
744
 
</p>
745
 
 
746
 
<p>
747
 
The basic usage of your app's <code>render()</code> method is to call it at least once, usually after you instantiate your app, this ensures the proper DOM structure is setup to handle rendering the app's <a href="#view-management">views</a>.
748
 
</p>
749
 
 
750
 
<pre class="code prettyprint">var app = new Y.App();
751
 
app.render();</pre>
752
 
 
753
 
 
754
 
<p>
755
 
This results in the HTML of the page looking like this:
756
 
</p>
757
 
 
758
 
<pre class="code prettyprint">&lt;body class=&quot;yui3-app&quot;&gt;
759
 
    ...
760
 
    &lt;div class=&quot;yui3-app-views&quot;&gt;&lt;&#x2F;div&gt;
761
 
&lt;&#x2F;body&gt;</pre>
762
 
 
763
 
 
764
 
<p>
765
 
By default, an app's <code>container</code> node will be the <code>&lt;body&gt;</code> element and its <code>viewContainer</code> node will be a new <code>&lt;div&gt;</code>.
766
 
</p>
767
 
 
768
 
<p>
769
 
<strong>Note:</strong> The <code>&quot;yui3-app&quot;</code> and <code>&quot;yui3-app-views&quot;</code> CSS classes are added to the <code>container</code> and <code>viewContainer</code> respectively â€” this happens when the app is rendered.
770
 
</p>
771
 
 
772
 
<h4 id="specifying-container-nodes">Specifying Container Nodes</h4>
773
 
 
774
 
<p>
775
 
When constructing a new App instance you can specify values for the app's <code>container</code> and <code>viewContainer</code> attributes, and they can even reference the same node.
776
 
</p>
777
 
 
778
 
<pre class="code prettyprint">var app = new Y.App({
779
 
    container    : &#x27;#wrapper&#x27;,
780
 
    viewContainer: &#x27;#wrapper&#x27;
781
 
});
782
 
 
783
 
app.render();</pre>
784
 
 
785
 
 
786
 
<p>
787
 
Assuming that a <code>&lt;div id=&quot;wrapper&quot;&gt;</code> node already exists on the page, this uses a CSS selector string to reference the node, assigns it to both containers, and results in the following HTML:
788
 
</p>
789
 
 
790
 
<pre class="code prettyprint">&lt;div id=&quot;wrapper&quot; class=&quot;yui3-app yui3-app-views&quot;&gt;
791
 
    ...
792
 
&lt;&#x2F;div&gt;</pre>
793
 
 
794
 
 
795
 
<p>
796
 
If you specify a <code>container</code> that is not already within the markup of the page, you'll need to manually append it to an element that is:
797
 
</p>
798
 
 
799
 
<pre class="code prettyprint">var app = new Y.App({
800
 
    container: Y.Node.create(&#x27;&lt;div id=&quot;fancy-app&quot; &#x2F;&gt;&#x27;)
801
 
});
802
 
 
803
 
app.render().get(&#x27;container&#x27;).appendTo(&#x27;body&#x27;);</pre>
804
 
 
805
 
 
806
 
<p>
807
 
This results in the HTML of the page looking like this:
808
 
</p>
809
 
 
810
 
<pre class="code prettyprint">&lt;body&gt;
811
 
    ...
812
 
    &lt;div id=&quot;fancy-app&quot; class=&quot;yui3-app&quot;&gt;
813
 
        &lt;div class=&quot;yui3-app-views&quot;&gt;&lt;&#x2F;div&gt;
814
 
    &lt;&#x2F;div&gt;
815
 
&lt;&#x2F;body&gt;</pre>
816
 
 
817
 
 
818
 
<p>
819
 
Refer to App's API Docs for more details about <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#attr_container"><code>container</code></a> and <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#attr_viewContainer"><code>viewContainer</code></a> attributes.
820
 
</p>
821
 
 
822
 
<h4 id="overriding-render">Overriding <code>render()</code></h4>
823
 
 
824
 
<p>
825
 
You may override the <code>render()</code> method to customize how the app renders itself, particularly if you are creating an App subclass.
826
 
</p>
827
 
 
828
 
<p>
829
 
<strong>Note:</strong> You should expect that the <code>viewContainer</code>'s contents will be modified by the app for the purpose of rendering the <code>activeView</code> when it changes; and ideally your <code>render()</code> method should also return <code>this</code> at the end to allow chaining, but that's up to you.
830
 
</p>
831
 
 
832
 
<p>
833
 
The following provides a templates for how you could subclass <code>Y.App</code> and implement a custom <code>render()</code> method while still preserving its default behavior:
834
 
</p>
835
 
 
836
 
<pre class="code prettyprint">Y.CustomApp = Y.Base.create(&#x27;customApp&#x27;, Y.App, [], {
837
 
    render: function () {
838
 
        &#x2F;&#x2F; This calls the superclass&#x27; (Y.App) implementation of the &#x60;render()&#x60;
839
 
        &#x2F;&#x2F; method to preserve the default behavior.
840
 
        Y.CustomApp.superclass.render.apply(this, arguments);
841
 
 
842
 
        &#x2F;&#x2F; Provide your custom rendering logic here.
843
 
 
844
 
        &#x2F;&#x2F; Returns this &#x60;Y.CustomApp&#x60; instance to allow for chaining.
845
 
        return this;
846
 
    }
847
 
});</pre>
848
 
 
849
 
 
850
 
<p>
851
 
Refer to App's API Docs for more details about the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#method_render"><code>render()</code> method</a>. See <a href="#subclassing">Subclassing</a> for more details on extending <code>Y.App</code>.
852
 
</p>
853
 
 
854
 
<h3 id="view-management">View Management</h3>
855
 
 
856
 
<p>
857
 
A primary feature of App is its flexible view management, which enables you to declare the primary views of your application and easily switch which one is active. This is very handy for defining your app's top-level "page" views, then switching between them as a user navigates through the application.
858
 
</p>
859
 
 
860
 
<h4 id="declaring-views">Declaring Views</h4>
861
 
 
862
 
<p>
863
 
The <code>views</code> property of an App class allows you to specify a mapping of view-names to view-metadata that should be registered to your app. This way you can specify information about your app's views â€” how they should be treated by the app, and how they related to other views â€” up-front, in a declarative way that is self-documenting.
864
 
</p>
865
 
 
866
 
<p>
867
 
You can setup this views mapping on both App subclasses and instances. Every App instance will receive its own copy of a <code>views</code> object, any <code>views</code> metadata defined at the class-level will be used as defaults and merged with any <code>views</code> specified during instantiation time.
868
 
</p>
869
 
 
870
 
<p>
871
 
The follow example shows the creation of an App subclass, <code>CustomApp</code>, which has a few default views defined, and an instance of <code>CustomApp</code> which defines another view and overrides some of the defaults.
872
 
</p>
873
 
 
874
 
<pre class="code prettyprint">&#x2F;&#x2F; Create a Y.CustomApp class that extends Y.App.
875
 
Y.CustomApp = Y.Base.create(&#x27;customApp&#x27;, Y.App, [], {
876
 
    &#x2F;&#x2F; Default registered views inherited by all CustomApp instances.
877
 
    views: {
878
 
        home : {preserve: true},
879
 
        users: {preserve: true},
880
 
        user : {parent: &#x27;users&#x27;}
881
 
    }
882
 
});
883
 
 
884
 
&#x2F;&#x2F; Create a CustomApp instance that inherits the defaults and adds to them.
885
 
var app = new Y.CustomApp({
886
 
    &#x2F;&#x2F; Additional view metadata to be merged with the defaults.
887
 
    views: {
888
 
        home : {preserve: false},
889
 
        user : {preserve: false},
890
 
        about: {preserve: true}
891
 
    }
892
 
});</pre>
893
 
 
894
 
 
895
 
<p>
896
 
Using the <code>getViewInfo()</code> method, we can see how the <code>views</code> metadata from our <code>CustomView</code> class and instance were merged together.
897
 
</p>
898
 
 
899
 
<pre class="code prettyprint">&#x2F;&#x2F; Overwrote &quot;home&quot;&#x27;s default &#x60;preserve&#x60; value.
900
 
Y.log(app.getViewInfo(&#x27;home&#x27;).preserve);  &#x2F;&#x2F; =&gt; false
901
 
 
902
 
&#x2F;&#x2F; Added &#x60;preserve&#x60; to &quot;user&quot; view,
903
 
&#x2F;&#x2F; and this did not overwrite the default &#x60;parent&#x60; value.
904
 
Y.log(app.getViewInfo(&#x27;user&#x27;).parent);    &#x2F;&#x2F; =&gt; &quot;home&quot;
905
 
Y.log(app.getViewInfo(&#x27;user&#x27;).preserve);  &#x2F;&#x2F; =&gt; false
906
 
 
907
 
&#x2F;&#x2F; The specified &quot;about&quot; view was registered.
908
 
Y.log(app.getViewInfo(&#x27;about&#x27;).preserve); &#x2F;&#x2F; =&gt; true</pre>
909
 
 
910
 
 
911
 
<p>
912
 
See the <a href="#app-properties">App Properties</a> section above for more details on what metadata can be stored for each view in <code>views</code> mapping.
913
 
</p>
914
 
 
915
 
<h4 id="switching-the-active-view">Switching the Active View</h4>
916
 
 
917
 
 
918
 
<p>
919
 
When decomposing an application into discrete user-interfaces, it is natural to think of these as different "pages"—with each one serving a particular role and being the main content on the screen. With the App component, changing the main content/user-interface is done by updating an app's <code>activeView</code> attribute via the <code>showView()</code> method.
920
 
</p>
921
 
 
922
 
<p>
923
 
Working in concert with an app's registered <code>views</code>, the <code>showView()</code> method will take a specified view and make it the app's <code>activeView</code>. This view will be "attached" to the app by rendering it inside the app's <code>viewContainer</code> and any custom events fired by the view will bubble to the app. Any previously active view will be "detached" from the app, removed from the DOM, and either preserved for later use or properly destroyed.
924
 
</p>
925
 
 
926
 
<p>
927
 
The following example is the most basic "Hello World" app:
928
 
</p>
929
 
 
930
 
<pre class="code prettyprint">&#x2F;&#x2F; Creates a new App and View instance.
931
 
var app  = new Y.App(),
932
 
    view = new Y.View();
933
 
 
934
 
&#x2F;&#x2F; Overrides the view&#x27;s &#x60;render()&#x60; method to render text into its &#x60;container&#x60;.
935
 
view.render = function () {
936
 
    this.get(&#x27;container&#x27;).set(&#x27;text&#x27;, &#x27;Hello World!&#x27;);
937
 
    return this;
938
 
};
939
 
 
940
 
&#x2F;&#x2F; Renders the &#x60;app&#x60; and &#x60;view&#x60;, then sets the view as the app&#x27;s &#x60;activeView&#x60;.
941
 
&#x2F;&#x2F; We have to explicity tell the app to render the view because by default, if
942
 
&#x2F;&#x2F; the view instance already exists it won&#x27;t be rendered automatically.
943
 
app.render().showView(view, null, {render: true});
944
 
 
945
 
&#x2F;&#x2F; Verify that &#x60;view&#x60; is now the &#x60;activeView&#x60;, and that the view&#x27;s &#x60;container&#x60;
946
 
&#x2F;&#x2F; is now rendered within the app&#x27;s &#x60;viewContainer&#x60;.
947
 
Y.log(app.get(&#x27;activeView&#x27;) === view);                           &#x2F;&#x2F; =&gt; true
948
 
Y.log(app.get(&#x27;viewContainer&#x27;).contains(view.get(&#x27;container&#x27;))); &#x2F;&#x2F; =&gt; true</pre>
949
 
 
950
 
 
951
 
<p>
952
 
This results in the HTML of the page looking like this:
953
 
</p>
954
 
 
955
 
<pre class="code prettyprint">&lt;body class=&quot;yui3-app&quot;&gt;
956
 
    ...
957
 
    &lt;div class=&quot;yui3-app-views&quot;&gt;
958
 
        &lt;div&gt;Hello World!&lt;&#x2F;div&gt;
959
 
    &lt;&#x2F;div&gt;
960
 
&lt;&#x2F;body&gt;</pre>
961
 
 
962
 
 
963
 
<p>
964
 
This example app can <em>easily</em> become dynamic and have the ability to say hello to someone by name. By creating a reusable <code>HelloView</code> class the app can dynamically switch between outputting "Hello World!" and "Hello [name]!" where the "name" is a path segment in the URL.
965
 
</p>
966
 
 
967
 
<pre class="code prettyprint">&#x2F;&#x2F; Creates a HelloView which can say hello to someone named, or to the World
968
 
&#x2F;&#x2F; if a name is not specified.
969
 
Y.HelloView = Y.Base.create(&#x27;helloView&#x27;, Y.View, [], {
970
 
    render: function () {
971
 
        var name = this.get(&#x27;name&#x27;);
972
 
        this.get(&#x27;container&#x27;).set(&#x27;text&#x27;, &#x27;Hello &#x27; + (name || &#x27;World&#x27;) + &#x27;!&#x27;);
973
 
        return this;
974
 
    }
975
 
});
976
 
 
977
 
&#x2F;&#x2F; Creates a new App instance and registers the HelloView.
978
 
var app = new Y.App({
979
 
    views: {
980
 
        hello: {type: &#x27;HelloView&#x27;}
981
 
    }
982
 
});
983
 
 
984
 
&#x2F;&#x2F; Adds a route handler for &quot;&#x2F;&quot; to show the HelloView.
985
 
app.route(&#x27;&#x2F;&#x27;, function (req) {
986
 
    &#x2F;&#x2F; Sets the &#x60;activeView&#x60; to a new instance of a &#x60;Y.HelloView&#x60; by just
987
 
    &#x2F;&#x2F; passing &quot;hello&quot;, the name of the registered view.
988
 
    this.showView(&#x27;hello&#x27;);
989
 
});
990
 
 
991
 
&#x2F;&#x2F; Adds a route handler for &quot;&#x2F;:name&quot; to show the HelloView with a &#x60;name&#x60;.
992
 
app.route(&#x27;&#x2F;:name&#x27;, function (req) {
993
 
    &#x2F;&#x2F; The name which we want to say hello to is specified on &#x60;req.params&#x60;.
994
 
    var name = req.params.name;
995
 
 
996
 
    &#x2F;&#x2F; Sets the &#x60;activeView&#x60; to a new instance of a &#x60;Y.HelloView&#x60;, but here
997
 
    &#x2F;&#x2F; we are also passing a config object which the new view instance will
998
 
    &#x2F;&#x2F; be constructed with, and it contains the name which we&#x27;ll say hello to.
999
 
    this.showView(&#x27;hello&#x27;, {name: name});
1000
 
});
1001
 
 
1002
 
&#x2F;&#x2F; Renders the app, then saves a new history entry for &quot;&#x2F;eric&quot; which will
1003
 
&#x2F;&#x2F; dispatch the &quot;&#x2F;:name&quot; route handler.
1004
 
app.render().save(&#x27;&#x2F;eric&#x27;);</pre>
1005
 
 
1006
 
 
1007
 
<p>
1008
 
This results in the URL being updated to either <code>&quot;&#x2F;eric&quot;</code> or <code>&quot;&#x2F;#&#x2F;eric&quot;</code> depending on whether the browser is capable of HTML5 history, and the HTML of the page looking like this:
1009
 
</p>
1010
 
 
1011
 
<pre class="code prettyprint">&lt;body class=&quot;yui3-app&quot;&gt;
1012
 
    ...
1013
 
    &lt;div class=&quot;yui3-app-views&quot;&gt;
1014
 
        &lt;div&gt;Hello eric!&lt;&#x2F;div&gt;
1015
 
    &lt;&#x2F;div&gt;
1016
 
&lt;&#x2F;body&gt;</pre>
1017
 
 
1018
 
 
1019
 
<h5 id="understanding-showview-options">Understanding <code>showView()</code> Options</h5>
1020
 
 
1021
 
<p>
1022
 
App's <code>showView()</code> method has the following signature:
1023
 
</p>
1024
 
 
1025
 
<pre class="code prettyprint">showView ( view  [config]  [options]  [callback] )</pre>
1026
 
 
1027
 
 
1028
 
<p>
1029
 
As seen in the previous usage examples, <code>view</code> can either be a view instance or the string-name of a view defined in the app's <code>views</code> object. The optional <code>config</code> object is used when creating a new view instance. The <code>config</code> object can also be used to update an existing or preserved <code>view</code>'s attributes when <code>options.update</code> is <code>true</code>.
1030
 
</p>
1031
 
 
1032
 
<p>
1033
 
The following is the list of <code>options</code> which affect how the app will switch its <code>activeView</code>:
1034
 
</p>
1035
 
 
1036
 
<dl>
1037
 
  <dt><code>callback</code></dt>
1038
 
  <dd>
1039
 
    <p>
1040
 
    Optional callback function to call after new <code>activeView</code> is ready to use, the function will be passed a reference to the view.
1041
 
    </p>
1042
 
 
1043
 
    <p>
1044
 
    Specifying a callback function is useful you need access to the view instance which is created as a result of calling <code>showView()</code>. Also, if an app is using transitions, the callback function will be called once the transitions have completed.
1045
 
    </p>
1046
 
  </dd>
1047
 
 
1048
 
  <dt><code>prepend</code></dt>
1049
 
  <dd>
1050
 
    <p>
1051
 
    Whether the <code>view</code> should be prepended instead of appended to the app's <code>viewContainer</code> node.
1052
 
    </p>
1053
 
 
1054
 
    <p>
1055
 
    This option is used internally to aid transitions by prepending the new <code>activeView</code> if it has been defined as the <code>parent</code> of the currently active view. This puts the view as the first child of the app's <code>viewContainer</code> node which helps the sliding transitions.
1056
 
    </p>
1057
 
  </dd>
1058
 
 
1059
 
  <dt><code>render</code></dt>
1060
 
  <dd>
1061
 
    <p>
1062
 
    Whether the <code>view</code> should be rendered. <strong>Note:</strong> If no value is specified, a view instance will only be rendered if it's newly created by this method.
1063
 
    </p>
1064
 
 
1065
 
    <p>
1066
 
    Sometimes you may need greater control over when a view is rendered. Under certain circumstances you may wish to re-render a preserved view, you can use this option to accomplish this.
1067
 
    </p>
1068
 
  </dd>
1069
 
 
1070
 
  <dt><code>transition</code></dt>
1071
 
  <dd>
1072
 
    <p>
1073
 
    Optional transition override. A transition can be specified which will override the default, or <code>false</code> for no transition.
1074
 
    </p>
1075
 
 
1076
 
    <p>
1077
 
    When an app is using transitions, this option allows you to override the default transition that will occur per the app's <code>transitions</code> configuration â€” enabling finer-grained control over how views transition.
1078
 
    </p>
1079
 
  </dd>
1080
 
 
1081
 
  <dt><code>update</code></dt>
1082
 
  <dd>
1083
 
    <p>
1084
 
    Whether an existing view should have its attributes updated by passing the <code>config</code> object to its <code>setAttrs()</code> method. <strong>Note:</strong> This option does not have an effect if the <code>view</code> instance is created as a result of calling this method.
1085
 
    </p>
1086
 
 
1087
 
    <p>
1088
 
    This option would usually be used to update a preserved view with new data and can be used in conjunction with the <code>render</code> option to force a view to update and re-render.
1089
 
    </p>
1090
 
  </dd>
1091
 
</dl>
1092
 
 
1093
 
<p>
1094
 
Refer to App's API docs</a> for more details about the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#method_showView"><code>showView()</code> method</a>.
1095
 
</p>
1096
 
 
1097
 
<h3 id="navigating-between-pages">Navigating Between "Pages"</h3>
1098
 
 
1099
 
<p>
1100
 
A key feature of <code>Y.App</code> is its robust URL navigation management. You can simply use standard HTML links within your app and when the user clicks a link, <code>Y.App</code> will handle it if there’s a matching route for that URL. With the <a href="#configuring-navigation-behavior">navigation-related config options</a> you have full control over your app's navigation behavior and experience, plus your app will automatically use the best available navigation method based on these settings, the browser’s capabilities, and the actions of the user.
1101
 
</p>
1102
 
 
1103
 
<p>
1104
 
This enables an app fulfill a "page request" by using data it already has stored in models or loading new data, then composing and showing a view which represents the app's current state for this URL â€” all without requiring a full page load.
1105
 
</p>
1106
 
 
1107
 
<h4 id="programmatic-navigation">Programmatic navigation</h4>
1108
 
 
1109
 
<p>
1110
 
Beyond handling navigation via link clicks, <code>Y.App</code> also exposes a programmatic way to navigate the user though your app via the <code>navigate()</code> method.
1111
 
</p>
1112
 
 
1113
 
<p>
1114
 
App's <code>navigate()</code> method implements a higher level concept of "browsing" over the <code>save()</code> and <code>replace()</code> methods. It will manage a user's navigation history like a browser, and is the recommended method to use when programmatically navigating the user to URLs within your app.
1115
 
</p>
1116
 
 
1117
 
<p>
1118
 
The <code>navigate()</code> method will do the right thing (what the browser would do) when navigating the user to the same URL they are currently on â€” it will replace the history entry â€” or to an in-page fragment identifier â€” which only when configured will navigate. The following demonstrates some of these behaviors:
1119
 
</p>
1120
 
 
1121
 
<pre class="code prettyprint">var app = new Y.App();
1122
 
 
1123
 
app.route(&#x27;*&#x27;, function (req, res, next) {
1124
 
    &#x2F;&#x2F; Handle all URLs.
1125
 
});
1126
 
 
1127
 
&#x2F;&#x2F; Save a new history entry for &quot;&#x2F;&quot;, or replaces the current entry if we&#x27;re
1128
 
&#x2F;&#x2F; already on &quot;&#x2F;&quot;.
1129
 
app.navigate(&#x27;&#x2F;&#x27;); &#x2F;&#x2F; =&gt; true
1130
 
 
1131
 
&#x2F;&#x2F; Does not navigate even though there&#x27;s a matching route handler.
1132
 
app.navigate(&#x27;#top&#x27;); &#x2F;&#x2F; =&gt; false
1133
 
 
1134
 
&#x2F;&#x2F; Enable navigation on hash-only changes to the URL.
1135
 
app.set(&#x27;navigateOnHash&#x27;, true);
1136
 
 
1137
 
&#x2F;&#x2F; Does navigate because &#x60;navigateOnHash&#x60; was enabled.
1138
 
app.navigate(&#x27;#top&#x27;); &#x2F;&#x2F; =&gt; true</pre>
1139
 
 
1140
 
 
1141
 
<p>
1142
 
Refer to App's API Docs for more details about the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#method_navigate"><code>navigate()</code> method</a>.
1143
 
</p>
1144
 
 
1145
 
<h4 id="configuring-navigation-behavior">Configuring Navigation Behavior</h4>
1146
 
 
1147
 
<p>
1148
 
The navigation features of <code>Y.App</code> are built on the <a href="http://yuilibrary.com/yui/docs/api/classes/PjaxBase.html">base pjax functionality</a>. This is what enables users to navigate to the different sections or "pages" of an app while avoiding full page loads.
1149
 
</p>
1150
 
 
1151
 
<p>
1152
 
The following are configuration attributes which define an app’s navigation behavior:
1153
 
</p>
1154
 
 
1155
 
<table>
1156
 
  <thead>
1157
 
    <tr>
1158
 
      <th>Attribute</th>
1159
 
      <th>Defined in</th>
1160
 
      <th>Default Value</th>
1161
 
      <th>Description</th>
1162
 
    </tr>
1163
 
  </thead>
1164
 
  <tbody>
1165
 
    <tr>
1166
 
      <td><code>linkSelector</code></td>
1167
 
      <td><code>Y.PjaxBase</code></td>
1168
 
      <td><code>&quot;a&quot;</code></td>
1169
 
      <td>
1170
 
        <p>
1171
 
        CSS selector string used to filter link click events so that only the links which match it will have the enhanced-navigation behavior of pjax applied.
1172
 
        </p>
1173
 
 
1174
 
        <p>
1175
 
        When a link is clicked and that link matches this selector, navigating to the link's <code>href</code> URL using the enhanced, pjax, behavior will be attempted; and the browser's default way to navigate to new pages will be the fallback.
1176
 
        </p>
1177
 
 
1178
 
        <p>
1179
 
        By default this selector will match <em>all</em> links on the page.
1180
 
        </p>
1181
 
      </td>
1182
 
    </tr>
1183
 
 
1184
 
    <tr>
1185
 
      <td><code>navigateOnHash</code></td>
1186
 
      <td><code>Y.PjaxBase</code></td>
1187
 
      <td><code>false</code></td>
1188
 
      <td>
1189
 
        <p>
1190
 
        Whether navigating to a hash-fragment identifier on the current page should be enhanced and cause the <code>navigate</code> event to fire.
1191
 
        </p>
1192
 
 
1193
 
        <p>
1194
 
        By default Pjax allows the browser to perform its default action when a user is navigating within a page by clicking in-page links (e.g. <code>&lt;a href=&quot;#top&quot;&gt;Top of page&lt;&#x2F;a&gt;</code>) and does not attempt to interfere or enhance in-page navigation.
1195
 
        </p>
1196
 
      </td>
1197
 
    </tr>
1198
 
 
1199
 
    <tr>
1200
 
      <td><code>scrollToTop</code></td>
1201
 
      <td><code>Y.PjaxBase</code></td>
1202
 
      <td><code>true</code></td>
1203
 
      <td>
1204
 
        <p>
1205
 
        Whether the page should be scrolled to the top after navigating to a URL.
1206
 
        </p>
1207
 
 
1208
 
        <p>
1209
 
        When the user clicks the browser's back button, the previous scroll position will be maintained.
1210
 
        </p>
1211
 
      </td>
1212
 
    </tr>
1213
 
 
1214
 
    <tr>
1215
 
      <td><code>serverRouting</code></td>
1216
 
      <td><code>Y.App.Base</code></td>
1217
 
      <td><code>undefined</code></td>
1218
 
      <td>
1219
 
        <p>
1220
 
        Whether or not this application's server is capable of properly routing all requests and rendering the initial state in the HTML responses.
1221
 
        </p>
1222
 
 
1223
 
        <p>
1224
 
        See <a href="#app-attributes">App Attributes</a> and <a href="#routing-coordination-with-server">Routing Coordination with Server</a> for more details.
1225
 
        </p>
1226
 
      </td>
1227
 
    </tr>
1228
 
  </tbody>
1229
 
</table>
1230
 
 
1231
 
<h4 id="navigate-event"><code>navigate</code> Event</h4>
1232
 
 
1233
 
<p>
1234
 
When the user is navigating to a URL for which the app has a route handler, the <code>navigate</code> event will fire. The default action of this event updates the browser’s address bar to reflect the new URL, causing the app to dispatch to the matching route handlers.
1235
 
</p>
1236
 
 
1237
 
<p>
1238
 
Listening to your app's <code>navigate</code> event is a useful way to indicate to the user that something is loading while they wait for the app to fully handle the new URL, possibly loading data from a remote server.
1239
 
</p>
1240
 
 
1241
 
<pre class="code prettyprint">var app = new Y.App({
1242
 
    views: {
1243
 
        users: {}
1244
 
    },
1245
 
 
1246
 
    users: new Y.ModelList()
1247
 
});
1248
 
 
1249
 
app.route(&#x27;&#x2F;users&#x2F;&#x27;, function () {
1250
 
    var users = app.get(&#x27;users&#x27;);
1251
 
 
1252
 
    &#x2F;&#x2F; Load users data from a remote server.
1253
 
    users.load(function () {
1254
 
        app.showView(&#x27;users&#x27;, {users: users});
1255
 
 
1256
 
        &#x2F;&#x2F; Removes the &quot;loading&quot; class from the app&#x27;s &#x60;container&#x60; node.
1257
 
        app.get(&#x27;container&#x27;).removeClass(&#x27;loading&#x27;);
1258
 
    });
1259
 
});
1260
 
 
1261
 
&#x2F;&#x2F; Listen for the app&#x27;s &#x60;navigate&#x60; event.
1262
 
app.on(&#x27;navigate&#x27;, function (e) {
1263
 
    &#x2F;&#x2F; Adds the &quot;loading&quot; class to the app&#x27;s &#x60;container&#x60; node.
1264
 
    app.get(&#x27;container&#x27;).addClass(&#x27;loading&#x27;);
1265
 
});
1266
 
 
1267
 
&#x2F;&#x2F; Navigate the user to &quot;&#x2F;users&#x2F;&quot;.
1268
 
app.navigate(&#x27;&#x2F;users&#x2F;&#x27;);</pre>
1269
 
 
1270
 
 
1271
 
<p>
1272
 
Refer to App's API Docs for more details about the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#event_navigate"><code>navigate</code> event</a>.
1273
 
</p>
1274
 
 
1275
 
<h2 id="extending-yapp">Extending <code>Y.App</code></h2>
1276
 
 
1277
 
<p>
1278
 
The <code>Y.App</code> class is intended to be mutable insofar as being the host for <em>all</em> App-component features, whereas <code>Y.App.Base</code> is intended to remain pure and just host the basic set of features. This allows for two different ways to extend the functionality of <code>Y.App</code>: <a href="#mixing-in-features">mixing-in features</a>, and <a href="#subclassing">subclassing</a>.
1279
 
</p>
1280
 
 
1281
 
<h3 id="mixing-in-features">Mixing-In Features</h3>
1282
 
 
1283
 
<p>
1284
 
Additional class extensions can be automatically mixed-into <code>Y.App</code>, doing so will dynamically extend the functionality of the App class making these new features available to all of its instances and subclasses. The <a href="#yapptransitions"><code>Y.App.Transitions</code></a> class extension, provided by the <code>app-transitions</code> module, uses this pattern to add transitions support to <code>Y.App</code>.
1285
 
</p>
1286
 
 
1287
 
<pre class="code prettyprint">&#x2F;&#x2F; Creates the namespace for the transitions class extension and assigns a
1288
 
&#x2F;&#x2F; simple constructor function to it.
1289
 
Y.App.Transitions = function () {};
1290
 
 
1291
 
&#x2F;&#x2F; Defines the &#x60;transitions&#x60; attribute with a default value of &#x60;false&#x60;. This
1292
 
&#x2F;&#x2F; makes the view transitions an opt-in feature.
1293
 
Y.App.Transitions.ATTRS = {
1294
 
    transitions: {value: false}
1295
 
};
1296
 
 
1297
 
&#x2F;&#x2F; This defines the prototype of the transitions class extension, the actual
1298
 
&#x2F;&#x2F; implementation has been left out for the sake of simplicity.
1299
 
Y.App.Transitions.prototype = {
1300
 
 
1301
 
    &#x2F;&#x2F; The implementation of the transition features would be here.
1302
 
 
1303
 
};
1304
 
 
1305
 
&#x2F;&#x2F; Here the transitions class extension is being applied automatically by
1306
 
&#x2F;&#x2F; mixing itself into the &#x60;Y.App&#x60; class.
1307
 
Y.Base.mix(Y.App, [Y.App.Transitions]);</pre>
1308
 
 
1309
 
 
1310
 
<p>
1311
 
When this module is included in the YUI instance, the transitions support for App can be used by simply toggling it on:
1312
 
</p>
1313
 
 
1314
 
<pre class="code prettyprint">YUI().use(&#x27;app-base&#x27;, &#x27;app-transitions&#x27;, function (Y) {
1315
 
    var app = new Y.App({transitions: true});
1316
 
});</pre>
1317
 
 
1318
 
 
1319
 
<p>
1320
 
When writing your own class extensions to add features to <code>Y.App</code>, feel free to add them to App's namespace (e.g., <code>Y.App.SomeNewFeature</code>), and be sure to follow these two rules:
1321
 
</p>
1322
 
 
1323
 
<ol>
1324
 
  <li>
1325
 
    <p>
1326
 
    The addition functionality should be <strong>disabled by default</strong>. The API for the class extensions should provide some way for the user to <em>opt-in</em> to using the features it adds.
1327
 
    </p>
1328
 
 
1329
 
    <p>
1330
 
    The <code>Y.App.Transitions</code> class extension does this be requiring a "truthy" value for the <code>transitions</code> attribute. By default the value will be <code>false</code>, making this an opt-in feature.
1331
 
    </p>
1332
 
  </li>
1333
 
 
1334
 
  <li>
1335
 
    <p>
1336
 
    Be courteous to the other App component class extensions, since they all share the same <code>prototype</code> be careful not to unintentionally overwrite other properties or methods.
1337
 
    </p>
1338
 
  </li>
1339
 
</ol>
1340
 
 
1341
 
<h3 id="subclassing">Subclassing</h3>
1342
 
 
1343
 
<p>
1344
 
Creating class extensions for <a href="#mixing-in-features">mixing-in features</a> to <code>Y.App</code> is a great way to extend its functionality in a reusable way while not changing how you <a href="#instantiating-app">Instantiate an App</a>; but might find it more useful to extend the <code>Y.App</code> class to create a subclass customized to your specific needs.
1345
 
</p>
1346
 
 
1347
 
<p>
1348
 
Use the <code>Y.Base.create()</code> method to extend <code>Y.App</code> and add or override prototype and static members and attributes. You may also optionally specify one or more <a href="../base/index.html#extensions">class extensions</a> to mix into your new class.
1349
 
</p>
1350
 
 
1351
 
<pre class="code prettyprint">&#x2F;&#x2F; Create a Y.CustomApp class that extends Y.App.
1352
 
Y.CustomApp = Y.Base.create(&#x27;customApp&#x27;, Y.App, [], {
1353
 
    &#x2F;&#x2F; Add or override prototype properties and methods here.
1354
 
}, {
1355
 
    &#x2F;&#x2F; Add static properties and methods here.
1356
 
 
1357
 
    ATTRS: {
1358
 
        &#x2F;&#x2F; Add or override default attributes here.
1359
 
    }
1360
 
});</pre>
1361
 
 
1362
 
 
1363
 
<p>
1364
 
One benefit of extending <code>Y.App</code> is that you can easily add default views, routes, and route handlers to your custom App class, and they'll be shared by all instances of that class unless overridden at the instance level:
1365
 
</p>
1366
 
 
1367
 
<pre class="code prettyprint">&#x2F;&#x2F; Create a Y.CustomApp class that extends Y.App.
1368
 
Y.CustomApp = Y.Base.create(&#x27;customApp&#x27;, Y.App, [], {
1369
 
    &#x2F;&#x2F; Default registered views inherited by all CustomApp instances.
1370
 
    views: {
1371
 
        home : {preserve: true},
1372
 
        users: {preserve: true},
1373
 
        user : {parent: &#x27;users&#x27;}
1374
 
    },
1375
 
 
1376
 
    &#x2F;&#x2F; Default route handlers inherited by all CustomApp instances.
1377
 
 
1378
 
    handleHome: function (req) {
1379
 
        &#x2F;&#x2F; Handle the &quot;&#x2F;&quot; route here.
1380
 
    },
1381
 
 
1382
 
    handleUsers: function (req) {
1383
 
        &#x2F;&#x2F; Handle the &quot;&#x2F;users&#x2F;&quot; route here.
1384
 
    },
1385
 
 
1386
 
    handleUser: function (req) {
1387
 
        &#x2F;&#x2F; Handle the &quot;&#x2F;users&#x2F;:name&#x2F;&quot; route here.
1388
 
    }
1389
 
}, {
1390
 
    ATTRS: {
1391
 
        &#x2F;&#x2F; Share these routes with all CustomApp instances.
1392
 
        routes: {
1393
 
            value: [
1394
 
                {path: &#x27;&#x2F;&#x27;,             callback: &#x27;handleHome&#x27;},
1395
 
                {path: &#x27;&#x2F;users&#x2F;&#x27;,       callback: &#x27;handleUsers&#x27;}
1396
 
                {path: &#x27;&#x2F;users&#x2F;:name&#x2F;&#x27;, callback: &#x27;handleUser&#x27;}
1397
 
            ]
1398
 
        }
1399
 
    }
1400
 
});
1401
 
 
1402
 
&#x2F;&#x2F; Create a CustomApp instance that inherits the defaults and adds to them.
1403
 
var app = new Y.CustomApp({
1404
 
    &#x2F;&#x2F; Register an additional view. The &#x60;home&#x60;, &#x60;users&#x60;, and &#x60;user&#x60; views will
1405
 
    &#x2F;&#x2F; also be inherited.
1406
 
    views: {
1407
 
        about: {preserve: true}
1408
 
    }
1409
 
});
1410
 
 
1411
 
&#x2F;&#x2F; Add a route and route handler.
1412
 
app.route(&#x27;&#x2F;about&#x2F;&#x27;, function (req) {
1413
 
    &#x2F;&#x2F; Handle the &quot;&#x2F;about&#x2F;&quot; route here.
1414
 
});</pre>
1415
 
 
1416
 
 
1417
 
<p>
1418
 
Now all instances of <code>Y.CustomApp</code> will inherit all the custom defaults and can add to or override them. The <code>app</code> instance created here will handle the <code>&quot;&#x2F;&quot;</code>, <code>&quot;&#x2F;users&#x2F;&quot;</code>, and <code>&quot;&#x2F;users&#x2F;:name&#x2F;&quot;</code> routes in addition to its own <code>&quot;&#x2F;about&#x2F;&quot;</code> route.
1419
 
</p>
1420
 
 
1421
 
<p>
1422
 
Before you subclass <code>Y.App</code>, you should refer to <a href="http://yuilibrary.com/yui/docs/api/modules/app-base.html">App's API docs</a> to become familiar with its public and protected properties and methods.
1423
 
</p>
1424
 
 
1425
 
<h2 id="app-extensions">App Extensions</h2>
1426
 
 
1427
 
<h3 id="yapptransitions"><code>Y.App.Transitions</code></h3>
1428
 
 
1429
 
<p>
1430
 
The <a href="http://yuilibrary.com/yui/docs/api/classes/App.Transitions.html">Transitions</a> extension provides view transitions for apps in browsers which support native CSS3 transitions. View transitions visually enhance the change from one "page" to the next that is both pleasant to the user and helps to communicate a hierarchy between sections of an application.
1431
 
</p>
1432
 
 
1433
 
<h4 class="no-toc">Enabling Transitions</h4>
1434
 
 
1435
 
<p>
1436
 
Enabling transitions for an app just requires <em>opting-in</em>. The following will create a new <code>Y.App</code> instance with the default transitions enabled:
1437
 
</p>
1438
 
 
1439
 
<pre class="code prettyprint">var app = new Y.App({transitions: true});</pre>
1440
 
 
1441
 
 
1442
 
<p>
1443
 
With transitions enabled for an app, anytime the app's <code>activeView</code> changes, there will be a visual transition from the old to the new active view. How an app's <code>views</code> are configured effects which transition will be used, e.g. when changing between views which have a hierarchical relationship a sliding transition will be used.
1444
 
</p>
1445
 
 
1446
 
<h4 class="no-toc">Types of <code>activeView</code> Changes</h4>
1447
 
 
1448
 
<p>
1449
 
The following are the types of <code>activeView</code> changes for which transitions can be defined that correspond to the relationship between the new and old <code>activeView</code>:
1450
 
</p>
1451
 
 
1452
 
<dl>
1453
 
  <dt><code>navigate</code></dt>
1454
 
  <dd>
1455
 
    <p>
1456
 
    The default transition to use when changing the <code>activeView</code> of the application. This will be <strong><code>&quot;fade&quot;</code></strong> by default.
1457
 
    </p>
1458
 
  </dd>
1459
 
 
1460
 
  <dt><code>toChild</code></dt>
1461
 
  <dd>
1462
 
    <p>
1463
 
    The transition to use when the new <code>activeView</code> is configured as a child of the previously active view via its <code>parent</code> property as defined in this app's <code>views</code>. This will be <strong><code>&quot;slideLeft&quot;</code></strong> by default.
1464
 
    </p>
1465
 
  </dd>
1466
 
 
1467
 
  <dt><code>toParent</code></dt>
1468
 
  <dd>
1469
 
    <p>
1470
 
    The transition to use when the new <code>activeView</code> is configured as the <code>parent</code> of the previously active view as defined in this app's <code>views</code>. This will be <strong><code>&quot;slideRight&quot;</code></strong> by default.
1471
 
    </p>
1472
 
  </dd>
1473
 
</dl>
1474
 
 
1475
 
<h4 class="no-toc">Overriding Default Transitions</h4>
1476
 
 
1477
 
<p>
1478
 
The default transitions can be overridden in the following ways:
1479
 
</p>
1480
 
 
1481
 
<ul>
1482
 
  <li>
1483
 
    <p>
1484
 
    Overriding the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#property_transitions"><code>transitions</code> property</a> which is used as the default transitions for all <code>Y.App</code> instances.
1485
 
    </p>
1486
 
  </li>
1487
 
 
1488
 
  <li>
1489
 
    <p>
1490
 
    Specifying a <code>transitions</code> configuration object when instantiating a new app, which sets the app's <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#attr_transitions"><code>transitions</code> attribute</a>.
1491
 
    </p>
1492
 
  </li>
1493
 
 
1494
 
  <li>
1495
 
    <p>
1496
 
    Specifying a <code>transition</code> when calling the <a href="http://yuilibrary.com/yui/docs/api/classes/App.html#method_showView"><code>showView()</code> method</a>.
1497
 
    </p>
1498
 
  </li>
1499
 
</ul>
1500
 
 
1501
 
<p>
1502
 
The following example will override which transitions should be used by default, and specifically set the <code>transition</code> option on certain calls to <code>showView()</code>.
1503
 
</p>
1504
 
 
1505
 
<pre class="code prettyprint">var app = new Y.App({
1506
 
    &#x2F;&#x2F; The app&#x27;s three views and their relationships between one another.
1507
 
    views: {
1508
 
        home   : {},
1509
 
        about  : {},
1510
 
        contact: {parent: &#x27;about&#x27;},
1511
 
        team   : {parent: &#x27;about&#x27;}
1512
 
    },
1513
 
 
1514
 
    &#x2F;&#x2F; Overrides the default transitions types all to &quot;fade&quot; which will
1515
 
    &#x2F;&#x2F; cross-fade between &#x60;activeView&#x60; changes.
1516
 
    transitions: {
1517
 
        navigate: &#x27;fade&#x27;,
1518
 
        toChild : &#x27;fade&#x27;,
1519
 
        toParent: &#x27;fade&#x27;
1520
 
    },
1521
 
 
1522
 
    &#x2F;&#x2F; The app&#x27;s &#x60;team&#x60; model list for use by the &quot;team&quot; view.
1523
 
    team: new Y.ModelList().reset([
1524
 
        {name: &#x27;Eric Ferraiuolo&#x27;},
1525
 
        {name: &#x27;Ryan Grove&#x27;}
1526
 
    ])
1527
 
});
1528
 
 
1529
 
app.route(&#x27;&#x2F;&#x27;, function () {
1530
 
    &#x2F;&#x2F; Will transition via &quot;fade&quot;.
1531
 
    app.showView(&#x27;home&#x27;);
1532
 
});
1533
 
 
1534
 
app.route(&#x27;&#x2F;about&#x2F;&#x27;, function () {
1535
 
    &#x2F;&#x2F; Will transition via &quot;fade&quot;, even though we maybe coming from a child
1536
 
    &#x2F;&#x2F; view (i.e. &quot;contact&quot; or &quot;team&quot;).
1537
 
    app.showView(&#x27;about&#x27;);
1538
 
});
1539
 
 
1540
 
app.route(&#x27;&#x2F;about&#x2F;contact&#x2F;&#x27;, function () {
1541
 
    &#x2F;&#x2F; Will transition via &quot;fade&quot;, even though we maybe coming from the parent
1542
 
    &#x2F;&#x2F; &quot;about&quot; view.
1543
 
    app.showView(&#x27;contact&#x27;);
1544
 
});
1545
 
 
1546
 
app.route(&#x27;&#x2F;about&#x2F;team&#x2F;&#x27;, function () {
1547
 
    &#x2F;&#x2F; Shows the &quot;team&quot; view, passing it the app&#x27;s &#x60;team&#x60; model list, and
1548
 
    &#x2F;&#x2F; overrides the &#x60;transition&#x60; options so no visual transitions will occur.
1549
 
    app.showView(&#x27;team&#x27;, {team: this.get(&#x27;team&#x27;)}, {transition: false});
1550
 
});
1551
 
 
1552
 
app.render().dispatch();</pre>
1553
 
 
1554
 
 
1555
 
<h4 class="no-toc">Transition-Aiding CSS</h4>
1556
 
 
1557
 
<p>
1558
 
Some structural CSS is required to setup an app's <code>container</code> and <code>viewContainer</code> nodes so the app's views transition properly. While an app's views are transitioning, the CSS class: <strong><code>yui3-app-transitioning</code></strong> will be added to the app's <code>container</code> node.
1559
 
</p>
1560
 
 
1561
 
<p>
1562
 
<strong>Note:</strong> While transitioning, the app's <code>viewContainer</code> node will have its <code>overflow-x</code> set to <code>hidden</code>. This causes its margins to <em>not collapse</em> with its child nodes. To compensate for this, it is best to not style your views with margins.
1563
 
</p>
1564
 
 
1565
 
<h2 id="best-practices">Best Practices</h2>
1566
 
 
1567
 
<h3 id="progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</h3>
1568
 
 
1569
 
<p>
1570
 
It's important to understand the difference between the preferred approach of developing an app using a progressive enhancement strategy vs. creating a client side-only app, and when it might be appropriate to do so. As discussed in the <a href="#routing-coordination-with-server">Routing Coordination with Server</a>, <code>Y.App</code> provides the tools and is flexible enough implement an app using either strategy, but <strong>there are drawbacks to client-only applications</strong>.
1571
 
</p>
1572
 
 
1573
 
<p>
1574
 
The following sections build on <a href="../router/index.html#best-practices">Router's Best Practices</a>, all of which apply, by looking at things from a higher level, application perspective:
1575
 
</p>
1576
 
 
1577
 
<h4 id="full-path-vs-hash-based-urls">Full-path vs. Hash-based URLs</h4>
1578
 
 
1579
 
<p>
1580
 
Before making a decision to use hash-based URLs in your application, you should <strong>be aware of their drawbacks</strong>.
1581
 
</p>
1582
 
 
1583
 
<p>
1584
 
A client-only app will use hash-based URLs instead of the standard, full-path URLs. When the server receives a request for a hash-based URL everything after and including the fragment identifier ("#") is lost. This means your application will have to rely on the JavaScript to finish fulfilling the request for the user.
1585
 
</p>
1586
 
 
1587
 
<p>
1588
 
The following shows how this information loss manifest itself:
1589
 
</p>
1590
 
 
1591
 
<pre class="code">Browser URL: http:&#x2F;&#x2F;example.com&#x2F;#&#x2F;foo&#x2F;bar&#x2F;
1592
 
Request URL: http:&#x2F;&#x2F;example.com&#x2F;</pre>
1593
 
 
1594
 
 
1595
 
<p>
1596
 
The request URL that the server will see is missing the entire path, this means every URL in your application looks to the server as if it's the same page! To prevent link rot in your application, you'll have to support the hash-based variation of your URLs indefinitely.
1597
 
</p>
1598
 
 
1599
 
<p>
1600
 
Ideally you should prefer full-path URLs (e.g., http://example.com/foo/bar/) for your application and be able to handle full page loads for browsers which are not capable of using HTML5 history. This requires a server capable of routing requests and rendering the initial state of the application in the HTML responses. This is the main idea behind a progressive enhancement development strategy â€” providing a better experience for more capable browsers/devices.
1601
 
</p>
1602
 
 
1603
 
<h4 id="performance-and-seo">Performance and SEO</h4>
1604
 
 
1605
 
<p>
1606
 
Client-only apps suffer in more places than just their URLs. There are <em>horrible side-effects</em> of using hash-based URLs: degradation in performance of rendering the app's initial state, and lack of SEO.
1607
 
</p>
1608
 
 
1609
 
<p>
1610
 
It is faster to render the initial state of an app on the server before delegating control to the client-side JavaScript. But in order to achieve this, the server must be capable of routing requests and rendering this initial state. This means your application needs to be using full-path URLs.
1611
 
</p>
1612
 
 
1613
 
<p>
1614
 
To render the initial state in a client-only app, the server has to send over the HTML "shell" page, which then makes more HTTP requests to get the JavaScript. Once the JavaScript has been downloaded and parsed, it can execute and construct the <code>Y.App</code> instance. The app now needs to fetch data from the server (yet another HTTP request), and then it can display the initial state. All while the user is staring at a blank page â€” which is a horrible user experience, especially on a mobile device with a slower connection.
1615
 
</p>
1616
 
 
1617
 
<p>
1618
 
Optimizing your app to be indexed by search engines is also relates to this. SEO requires that your app uses full-path URLs so the server can route requests and render the initial state. The basic functions of your app which you want to be indexable should work without JavaScript.
1619
 
</p>
1620
 
 
1621
 
<h4 id="when-client-only-apps-are-appropriate">When Client-only Apps are Appropriate</h4>
1622
 
 
1623
 
<p>
1624
 
Given all the drawbacks of client-only apps, there's one major advantage: <strong>they don't rely on the server</strong>. If your app needs to run off the filesystem, or be deployed to a "dumb" static file server, then this might be your only option.
1625
 
</p>
1626
 
 
1627
 
<p>
1628
 
Developing a client-only app using <code>Y.App</code> still gives you nice (but hash-based) URLs that are bookmarkable, browser back/forward button support, and view management.
1629
 
</p>
1630
 
 
1631
 
<p>
1632
 
<strong>Please make sure you understand the issues with hash-based URLs and their side-effects.</strong> Consider developing your application using a progressive enhancement strategy, it will be worth the extra effort in the long run.
1633
 
</p>
1634
 
 
1635
 
<h3 id="flow-control">Flow Control</h3>
1636
 
 
1637
 
<p>
1638
 
When developing an app, it's important to have a clear understanding about how the various components are working together. The use of consistent patterns for information sharing, and execution of operations aid in maintaining a separation of concerns which becomes ever more crucial as the size of the app and team increases.
1639
 
</p>
1640
 
 
1641
 
<p>
1642
 
Restricting the flow of information to a single direction creates a "one-way street" which enforces a strict separation of concerns and divides control over execution throughout an application. This strategy can be implemented by leveraging YUI's powerful custom event infrastructure. All of the components of App Framework are <code>Y.Base</code>-based, and therefore are primed to be both publishers and subscribers of an app's custom events.
1643
 
</p>
1644
 
 
1645
 
<p>
1646
 
The following example app demonstrates how to wire up the components of an application using custom events to achieve the one-way flow of information and divide control by maintaining a strict separation of concerns:
1647
 
</p>
1648
 
 
1649
 
<pre class="code prettyprint">&#x2F;&#x2F; Create the &#x60;UserView&#x60;.
1650
 
Y.UserView = Y.Base.create(&#x27;userView&#x27;, Y.View, [], {
1651
 
    template: &#x27;&lt;p&gt;{name}&lt;&#x2F;p&gt;&#x27; +
1652
 
              &#x27;&lt;label for=&quot;name-input&quot;&gt;Name:&lt;&#x2F;label&gt;&#x27; +
1653
 
              &#x27;&lt;input id=&quot;name-input&quot; type=&quot;text&quot; value=&quot;{name}&quot; &#x2F;&gt;&#x27; +
1654
 
              &#x27;&lt;button&gt;Save&lt;&#x2F;button&gt;&#x27;,
1655
 
 
1656
 
    &#x2F;&#x2F; Listens for DOM events from the user and translates them into application
1657
 
    &#x2F;&#x2F; events; e.g., &quot;click&quot; -&gt; &quot;save&quot;.
1658
 
    events: {
1659
 
        &#x27;button&#x27;: {click: &#x27;save&#x27;}
1660
 
    },
1661
 
 
1662
 
    initializer: function () {
1663
 
        &#x2F;&#x2F; Listens for the user model to change, and re-renders the view.
1664
 
        this.get(&#x27;user&#x27;).after(&#x27;change&#x27;, this.render, this);
1665
 
    },
1666
 
 
1667
 
    render: function () {
1668
 
        var user    = this.get(&#x27;user&#x27;),
1669
 
            content = Y.Lang.sub(this.template, {name: user.get(&#x27;name&#x27;)});
1670
 
 
1671
 
        this.get(&#x27;container&#x27;).setContent(content);
1672
 
        return this;
1673
 
    },
1674
 
 
1675
 
    &#x2F;&#x2F; This view doesn&#x27;t actually do the saving, instead, it is translating the
1676
 
    &#x2F;&#x2F; user&#x27;s intent (they click the Save button) to an application-level event.
1677
 
    &#x2F;&#x2F; This way control is given to the app to respond to this action.
1678
 
    save: function () {
1679
 
        var user = this.get(&#x27;user&#x27;),
1680
 
            name = this.get(&#x27;container&#x27;).one(&#x27;input&#x27;).get(&#x27;value&#x27;);
1681
 
 
1682
 
        &#x2F;&#x2F; Fires the save event and passes along the needed information. When
1683
 
        &#x2F;&#x2F; this is the app&#x27;s &#x60;activeView&#x60; this event will bubble to the app.
1684
 
        this.fire(&#x27;save&#x27;, {
1685
 
            user: user,
1686
 
            name: name
1687
 
        });
1688
 
    }
1689
 
});
1690
 
 
1691
 
&#x2F;&#x2F; Create the app and define the app&#x27;s &#x60;views&#x60;, and assign a new &#x60;Model&#x60;
1692
 
&#x2F;&#x2F; instance as an ad-hoc attribute to the app.
1693
 
var app = new Y.App({
1694
 
    views: {
1695
 
        user: {
1696
 
            type    : &#x27;UserView&#x27;,
1697
 
            preserve: true
1698
 
        }
1699
 
    },
1700
 
 
1701
 
    user: new Y.Model()
1702
 
});
1703
 
 
1704
 
&#x2F;&#x2F; The app listens for the &#x60;UserView&#x60; to fire its &#x60;save&#x60; event. The only will
1705
 
&#x2F;&#x2F; only be notified if the view is the app&#x27;s current &#x60;activeView&#x60;.
1706
 
app.on(&#x27;userView:save&#x27;, function (e) {
1707
 
    &#x2F;&#x2F; The app has the control to execute update the model and execute the save
1708
 
    &#x2F;&#x2F; operation. Updating the model will cause the view to re-render.
1709
 
    e.user.set(&#x27;name&#x27;, e.name).save();
1710
 
});
1711
 
 
1712
 
&#x2F;&#x2F; Renders the app and set&#x27;s the &#x60;user&#x60; view and the &#x60;activeView&#x60;, passing it
1713
 
&#x2F;&#x2F; the user model.
1714
 
app.render().showView(&#x27;user&#x27;, {user: app.get(&#x27;user&#x27;)});</pre>
1715
 
 
1716
 
 
1717
 
<p>
1718
 
The main thing to note about the above example is that the <code>UserView</code> is <em>not</em> updating its <code>user</code> model directly, instead it is translating the user's intent via DOM events into application-level events. This gives control back to the app so it can decide how best to proceed. The result is a flow of information and control that moves in one direction and in a continuous loop.
1719
 
</p>
1720
 
 
1721
 
<h3 id="preserved-views">Preserved Views</h3>
1722
 
 
1723
 
<p>
1724
 
An app's <code>views</code> can be defined so that a single instance of a particular view is preserved and can be reused. When a view is defined with its <code>preserve</code> property set to <code>true</code>, the same view instance will be used each time the app's <code>showView()</code> method is called to set it as the app's <code>activeView</code>.
1725
 
</p>
1726
 
 
1727
 
<p>
1728
 
Preserved views should be used in situations where the contents of the view might not change and that view will be displayed often. They are especially useful if its contents have a complex DOM structure that would be costly to create each time the view was to be shown.
1729
 
</p>
1730
 
 
1731
 
<p>
1732
 
Imagine a simple app that displays user information in two views: a <code>users</code> view that lists all the users, and a <code>user</code> view that displays the details of a single user. If the set of all users in this application won't change often, then it would be a good idea to make the <code>users</code> view a preserved view. That way it only has to be constructed once, and the same view instance can be shown many times. Whereas the contents of the <code>user</code> view are always going to change depending on which user is being displayed, making it <em>not</em> suitable to preserve.
1733
 
</p>
1734
 
 
1735
 
<p>
1736
 
The following example demonstrates how this hypothetical users app would define its two views:
1737
 
</p>
1738
 
 
1739
 
<pre class="code prettyprint">&#x2F;&#x2F; Create the &#x60;UsersView&#x60;.
1740
 
Y.UsersView = Y.Base.create(&#x27;usersView&#x27;, Y.View, [] {
1741
 
    &#x2F;&#x2F; Implementation would be here...
1742
 
});
1743
 
 
1744
 
&#x2F;&#x2F; Create the &#x60;UserView&#x60;.
1745
 
Y.UserView = Y.Base.create(&#x27;userView&#x27;, Y.View, [] {
1746
 
    &#x2F;&#x2F; Implementation would be here...
1747
 
});
1748
 
 
1749
 
&#x2F;&#x2F; Create the app and define its two views.
1750
 
var app = new Y.App({
1751
 
    views: {
1752
 
        &#x2F;&#x2F; Only one &#x60;users&#x60; view instance will be created and it will be
1753
 
        &#x2F;&#x2F; preserved for reuse.
1754
 
        users: {
1755
 
            preserve: true,
1756
 
            type    : &#x27;UsersView&#x27;
1757
 
        },
1758
 
 
1759
 
        &#x2F;&#x2F; A new &#x60;user&#x60; view instance will be created every time.
1760
 
        user: {
1761
 
            type  : &#x27;UserView&#x27;,
1762
 
            parent: &#x27;users&#x27;
1763
 
        }
1764
 
    }
1765
 
});</pre>
1766
 
 
1767
 
 
1768
 
<p>
1769
 
Be cautious about the number of preserved views you have in your application. Their DOM structures are maintained even when they are not in the visible portion of the page's DOM, this means the more preserved views, the more memory your application will consume. On mobile devices with very limited memory and no swap space, consuming too much memory in your app can cause the browser to crash.
1770
 
</p>
1771
 
 
1772
 
 
1773
 
 
1774
 
<h2 id="known-limitations">Known Limitations</h2>
1775
 
 
1776
 
<ul>
1777
 
  <li>
1778
 
    <p>
1779
 
    <strong>When multiple App instances are on the page, only one can manage the URL and navigation.</strong> All of the app instances can have route handlers, but only one should have its <code>linkSelector</code> attribute set to a non-falsy value. See <a href="#configuring-navigation-behavior">Configuring Navigation Behavior</a> for more details.
1780
 
    </p>
1781
 
  </li>
1782
 
 
1783
 
  <li>
1784
 
    <p>
1785
 
    <strong>Transitions are only supported in WebKit and Firefox browsers which also support CSS3 transitions.</strong> It is intended to only support transitions in browser which have native CSS3 transitions, and YUI's <a href="../transition/index.html">Transition</a> component only supports WebKit and Firefox.
1786
 
    </p>
1787
 
  </li>
1788
 
</ul>
1789
 
 
1790
 
<p>
1791
 
App relies heavily on Router which has some know limitations in Internet Explorer 9 and lower, and Android 2.x. See <a href="../router/index.html#known-limitations">Router's Known Limitations</a> for more details.
1792
 
</p>
1793
 
</div>
1794
 
            </div>
1795
 
        </div>
1796
 
 
1797
 
        <div class="yui3-u-1-4">
1798
 
            <div class="sidebar">
1799
 
                
1800
 
                    <div id="toc" class="sidebox">
1801
 
                        <div class="hd">
1802
 
                            <h2 class="no-toc">Table of Contents</h2>
1803
 
                        </div>
1804
 
 
1805
 
                        <div class="bd">
1806
 
                            <ul class="toc">
1807
 
<li>
1808
 
<a href="#getting-started">Getting Started</a>
1809
 
</li>
1810
 
<li>
1811
 
<a href="#components-of-the-app-framework">Components of the App Framework</a>
1812
 
</li>
1813
 
<li>
1814
 
<a href="#app-component">App Component</a>
1815
 
</li>
1816
 
<li>
1817
 
<a href="#using-app">Using App</a>
1818
 
<ul class="toc">
1819
 
<li>
1820
 
<a href="#instantiating-app">Instantiating App</a>
1821
 
<ul class="toc">
1822
 
<li>
1823
 
<a href="#config-properties">Config Properties</a>
1824
 
</li>
1825
 
</ul>
1826
 
</li>
1827
 
<li>
1828
 
<a href="#app-properties">App Properties</a>
1829
 
</li>
1830
 
<li>
1831
 
<a href="#app-attributes">App Attributes</a>
1832
 
</li>
1833
 
<li>
1834
 
<a href="#routing-coordination-with-server">Routing Coordination with Server</a>
1835
 
<ul class="toc">
1836
 
<li>
1837
 
<a href="#urls-based-on-browser-capabilities">URLs Based on Browser Capabilities</a>
1838
 
</li>
1839
 
<li>
1840
 
<a href="#full-path-urls-only">Full-path URLs Only</a>
1841
 
</li>
1842
 
<li>
1843
 
<a href="#hash-based-urls-only">Hash-based URLs Only</a>
1844
 
</li>
1845
 
</ul>
1846
 
</li>
1847
 
<li>
1848
 
<a href="#rendering-an-app">Rendering an App</a>
1849
 
<ul class="toc">
1850
 
<li>
1851
 
<a href="#specifying-container-nodes">Specifying Container Nodes</a>
1852
 
</li>
1853
 
<li>
1854
 
<a href="#overriding-render">Overriding <code>render()</code></a>
1855
 
</li>
1856
 
</ul>
1857
 
</li>
1858
 
<li>
1859
 
<a href="#view-management">View Management</a>
1860
 
<ul class="toc">
1861
 
<li>
1862
 
<a href="#declaring-views">Declaring Views</a>
1863
 
</li>
1864
 
<li>
1865
 
<a href="#switching-the-active-view">Switching the Active View</a>
1866
 
<ul class="toc">
1867
 
<li>
1868
 
<a href="#understanding-showview-options">Understanding <code>showView()</code> Options</a>
1869
 
</li>
1870
 
</ul>
1871
 
</li>
1872
 
</ul>
1873
 
</li>
1874
 
<li>
1875
 
<a href="#navigating-between-pages">Navigating Between "Pages"</a>
1876
 
<ul class="toc">
1877
 
<li>
1878
 
<a href="#programmatic-navigation">Programmatic navigation</a>
1879
 
</li>
1880
 
<li>
1881
 
<a href="#configuring-navigation-behavior">Configuring Navigation Behavior</a>
1882
 
</li>
1883
 
<li>
1884
 
<a href="#navigate-event"><code>navigate</code> Event</a>
1885
 
</li>
1886
 
</ul>
1887
 
</li>
1888
 
</ul>
1889
 
</li>
1890
 
<li>
1891
 
<a href="#extending-yapp">Extending <code>Y.App</code></a>
1892
 
<ul class="toc">
1893
 
<li>
1894
 
<a href="#mixing-in-features">Mixing-In Features</a>
1895
 
</li>
1896
 
<li>
1897
 
<a href="#subclassing">Subclassing</a>
1898
 
</li>
1899
 
</ul>
1900
 
</li>
1901
 
<li>
1902
 
<a href="#app-extensions">App Extensions</a>
1903
 
<ul class="toc">
1904
 
<li>
1905
 
<a href="#yapptransitions"><code>Y.App.Transitions</code></a>
1906
 
</li>
1907
 
</ul>
1908
 
</li>
1909
 
<li>
1910
 
<a href="#best-practices">Best Practices</a>
1911
 
<ul class="toc">
1912
 
<li>
1913
 
<a href="#progressively-enhanced-vs-client-only-apps">Progressively-enhanced vs. Client-only Apps</a>
1914
 
<ul class="toc">
1915
 
<li>
1916
 
<a href="#full-path-vs-hash-based-urls">Full-path vs. Hash-based URLs</a>
1917
 
</li>
1918
 
<li>
1919
 
<a href="#performance-and-seo">Performance and SEO</a>
1920
 
</li>
1921
 
<li>
1922
 
<a href="#when-client-only-apps-are-appropriate">When Client-only Apps are Appropriate</a>
1923
 
</li>
1924
 
</ul>
1925
 
</li>
1926
 
<li>
1927
 
<a href="#flow-control">Flow Control</a>
1928
 
</li>
1929
 
<li>
1930
 
<a href="#preserved-views">Preserved Views</a>
1931
 
</li>
1932
 
</ul>
1933
 
</li>
1934
 
<li>
1935
 
<a href="#known-limitations">Known Limitations</a>
1936
 
</li>
1937
 
</ul>
1938
 
                        </div>
1939
 
                    </div>
1940
 
                
1941
 
 
1942
 
                
1943
 
                    <div class="sidebox">
1944
 
                        <div class="hd">
1945
 
                            <h2 class="no-toc">Examples</h2>
1946
 
                        </div>
1947
 
 
1948
 
                        <div class="bd">
1949
 
                            <ul class="examples">
1950
 
                                
1951
 
                                    
1952
 
                                        <li data-description="A basic todo list built with the Model, Model List, and View components.">
1953
 
                                            <a href="app-todo.html">Todo List</a>
1954
 
                                        </li>
1955
 
                                    
1956
 
                                
1957
 
                                    
1958
 
                                        <li data-description="An application to browse through the contributors of a GitHub project.">
1959
 
                                            <a href="app-contributors.html">GitHub Contributors</a>
1960
 
                                        </li>
1961
 
                                    
1962
 
                                
1963
 
                            </ul>
1964
 
                        </div>
1965
 
                    </div>
1966
 
                
1967
 
 
1968
 
                
1969
 
            </div>
1970
 
        </div>
1971
 
    </div>
1972
 
</div>
1973
 
 
1974
 
<script src="../assets/vendor/prettify/prettify-min.js"></script>
1975
 
<script>prettyPrint();</script>
1976
 
 
1977
 
</body>
1978
 
</html>