Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

1660 lines (1429 sloc) 126.53 kb
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ember.js - Documentation</title>
<link href="/stylesheets/site.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/highlight.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="/javascripts/waypoints.min.js" type="text/javascript"></script>
<script type="text/javascript">
(function($){
$.fn.anchorScroll = function(){
this.click(function(event){
event.preventDefault();
var parts = this.href.split("#"),
target = parts[1],
offset = $('#'+target).offset(),
top = offset.top;
$('html, body').animate({scrollTop: top}, 500);
});
};
$(function(){
$('.toc a').anchorScroll();
$('#sidebar').waypoint(function(event,direction){
$('.toc').toggleClass('sticky', direction === "down");
}, {offset: '0'});
$('.section').waypoint(function(element,direction){
var element = $(this),
id = element.attr('id'),
anchor = $('a[href=#'+id+']'),
previousAnchor = anchor.closest('li').prev().find('a'),
activeAnchor = direction === 'down' ? anchor : previousAnchor;
$('.toc a').removeClass('active');
activeAnchor.addClass('active');
});
});
})($)
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-27675533-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<div id="header">
<div id="wrapper">
<div id="logo">&nbsp;</div>
<ul id="nav">
<li class="active"><a href="/documentation">docs</a></li>
<li><a href="/community">community</a></li>
<li><a href="/examples">examples</a></li>
</ul>
</div>
</div>
<div id="github">
<a href="https://github.com/emberjs/ember.js"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://a248.e.akamai.net/assets.github.com/img/e6bef7a091f5f3138b8cd40bc3e114258dd68ddf/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub"></a>
</div>
<div id="download">
<div id="download-ember">
<a href="https://github.com/downloads/emberjs/ember.js/ember-0.9.6.min.js">
<img src="/images/download_button.png">
</a>
<div class="info">39k min+gzip |
<a class="debug" href="https://github.com/downloads/emberjs/ember.js/ember-0.9.6.js">
debug build
</a>
</div>
</div>
<div id="download-starter-kit">
<a href="https://github.com/downloads/emberjs/starter-kit/starter-kit.0.9.6.zip">
<img src="/images/download_starter_kit_button.png">
</a>
</div>
</div>
<div id="content-wrapper">
<div id="sidebar">
<h3>Table of Contents</h2>
<ul>
<li>
<ul>
<li>
<a href="#toc_introduction">Introduction</a><ul>
<li>
<a href="#toc_what-is-ember-js">What is Ember.js?</a></li>
<li>
<a href="#toc_how-is-ember-js-different">How is Ember.js Different?</a></li>
<li>
<a href="#toc_ember-js-at-a-glance">Ember.js at a Glance</a></li>
</ul>
</li>
<li>
<a href="#toc_the-ember-object-model">The Ember Object Model</a><ul>
<li>
<a href="#toc_subclassing-classes">Subclassing Classes</a></li>
<li>
<a href="#toc_reopening-classes-and-instances">Reopening Classes and Instances</a></li>
<li>
<a href="#toc_computed-properties-getters">Computed Properties (Getters)</a></li>
<li>
<a href="#toc_computed-properties-setters">Computed Properties (Setters)</a></li>
<li>
<a href="#toc_observers">Observers</a></li>
<li>
<a href="#toc_bindings">Bindings</a></li>
<li>
<a href="#toc_what-do-i-use-when">What Do I Use When?</a></li>
</ul>
</li>
<li>
<a href="#toc_creating-a-namespace">Creating a Namespace</a></li>
<li>
<a href="#toc_describing-your-ui-with-handlebars">Describing Your UI with Handlebars</a><ul>
<li>
<a href="#toc_handlebars">Handlebars</a></li>
<li>
<a href="#toc_ember-view">Ember.View</a></li>
<li>
<a href="#toc_handlebars-basics">Handlebars Basics</a></li>
<li>
<a href="#toc_if-else-and-unless">{{#if}}, {{else}}, and {{#unless}}</a></li>
<li>
<a href="#toc_with">{{#with}}</a></li>
<li>
<a href="#toc_binding-element-attributes-with-bindattr">Binding Element Attributes with {{bindAttr}}</a></li>
<li>
<a href="#toc_binding-class-names-with-bindattr">Binding Class Names with {{bindAttr}}</a></li>
<li>
<a href="#toc_handling-events-with-action">Handling Events with {{action}}</a></li>
<li>
<a href="#toc_building-a-view-hierarchy">Building a View Hierarchy</a></li>
<li>
<a href="#toc_view">{{view}}</a></li>
<li>
<a href="#toc_setting-child-view-templates">Setting Child View Templates</a></li>
<li>
<a href="#toc_setting-up-bindings">Setting Up Bindings</a></li>
<li>
<a href="#toc_modifying-a-view-s-html">Modifying a View's HTML</a></li>
<li>
<a href="#toc_displaying-a-list-of-items">Displaying a List of Items</a></li>
<li>
<a href="#toc_writing-custom-helpers">Writing Custom Helpers</a></li>
<li>
<a href="#toc_included-views">Included Views</a></li>
</ul>
</li>
<li>
<a href="#toc_views-in-depth">Views In-Depth</a><ul>
<li>
<a href="#toc_handling-events">Handling Events</a></li>
<li>
<a href="#toc_manually-managed-views-with-ember-containerview">Manually Managed Views with Ember.ContainerView</a></li>
<li>
<a href="#toc_render-pipeline">Render Pipeline</a></li>
<li>
<a href="#toc_customizing-the-html-element">Customizing the HTML Element</a></li>
<li>
<a href="#toc_attribute-bindings-on-a-view">Attribute Bindings on a View</a></li>
</ul>
</li>
<li>
<a href="#toc_the-ember-enumerable-api">The Ember Enumerable API</a><ul>
<li>
<a href="#toc_what-are-enumerables">What Are Enumerables?</a></li>
<li>
<a href="#toc_enumerables-in-ember">Enumerables in Ember</a></li>
<li>
<a href="#toc_the-enumerable-interface">The Enumerable Interface</a>
</div>
<div id="content" class="has-sidebar">
<div class="section" id="introduction">
<h2 id='toc_introduction'>Introduction</h2><h3 id='toc_what-is-ember-js'>What is Ember.js?</h3>
<p>Ember is a JavaScript framework for creating ambitious web applications
that eliminates boilerplate and provides a standard application
architecture.</p>
<h4 id='toc_eliminate-boilerplate'>Eliminate Boilerplate</h4>
<p>There are some tasks that are common to every web application. For example,
taking data from the server, rendering it to the screen, then updating that
information when it changes.</p>
<p>Since the tools provided to do this by the browser are quite primitive, you
end up writing the same code over and over. Ember.js provides tools that let
you focus on your app instead of writing the same code you&#39;ve written a hundred
times.</p>
<p>Because we&#39;ve built dozens of applications ourselves, we&#39;ve gone beyond the
obvious low-level event-driven abstractions, eliminating much of the
boilerplate associated with propagating changes throughout your application,
and especially into the DOM itself.</p>
<p>To help manage changes in the view, Ember.js comes with a templating engine
that will automatically update the DOM when the underlying objects change.</p>
<p>For a simple example, consider this template of a Person:</p>
<div class="highlight"><pre>{{person.name}} is {{person.age}}.
</pre>
</div>
<p>As with any templating system, when the template is initially rendered, it
will reflect the current state of the person. To avoid boilerplate, though,
Ember.js will also update the DOM automatically for you if the person&#39;s name
or age changes.</p>
<p>You specify your template once, and Ember.js makes sure it&#39;s always up to date.</p>
<h4 id='toc_provides-architecture'>Provides Architecture</h4>
<p>Since web applications evolved from web pages, which were nothing more than
static documents, browsers give you just enough rope to hang yourself with.</p>
<p>Ember makes it easy to divide your application into models, views, and controllers,
which improves testability, makes code more modular, and helps new developers
on the project quickly understand how everything fits together. The days of
callback spaghetti are over.</p>
<p>Ember also supplies built-in support for state management, so you&#39;ll have
a way to describe how your application moves through various nested states
(like signed-out, signed-in, viewing-post, and viewing-comment) out of the box.</p>
<h3 id='toc_how-is-ember-js-different'>How is Ember.js Different?</h3>
<p>Traditional web applications make the user to download a new page every time
they interact with the server. This means that every interaction is never faster
than the latency between you and the user, and usually slower. Using AJAX to
replace only parts of the page helps somewhat, but still requires a roundtrip to
your server every time your UI needs to update. And if multiple parts of the
page need to update all at once, most developers just resort to loading the page
over again, since keeping everything in sync is tricky.</p>
<p>Ember.js, like some other modern JavaScript frameworks, works a little differently.
Instead of the majority of your application&#39;s logic living on the server, an
Ember.js application downloads everything it needs to run in the initial page
load. That means that while your user is using your app, she never has to load
a new page and your UI responds quickly to their interaction.</p>
<p>One advantage of this architecture is that your web application uses the same
REST API as your native apps or third-party clients. Back-end developers can
focus on building a fast, reliable, and secure API server, and don&#39;t have to be
front-end experts, too.</p>
<h3 id='toc_ember-js-at-a-glance'>Ember.js at a Glance</h3>
<p>These are the three features that make Ember a joy to use:</p>
<ol>
<li>Bindings</li>
<li>Computed properties</li>
<li>Auto-updating templates</li>
</ol>
<h4 id='toc_bindings'>Bindings</h4>
<p>Use bindings to keep properties between two different objects in sync. You just
declare a binding once, and Ember will make sure changes get propagated in either
direction.</p>
<p>Here&#39;s how you create a binding between two objects:</p>
<div class="highlight"><pre><span class="nx">MyApp</span><span class="p">.</span><span class="nx">president</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Barack Obama&quot;</span>
<span class="p">});</span>
<span class="nx">MyApp</span><span class="p">.</span><span class="nx">country</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="c1">// Ending a property with &#39;Binding&#39; tells Ember to</span>
<span class="c1">// create a binding to the presidentName property.</span>
<span class="nx">presidentNameBinding</span><span class="o">:</span> <span class="s1">&#39;MyApp.president.name&#39;</span>
<span class="p">});</span>
<span class="c1">// Later, after Ember has resolved bindings...</span>
<span class="nx">MyApp</span><span class="p">.</span><span class="nx">country</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;presidentName&#39;</span><span class="p">);</span>
<span class="c1">// &quot;Barack Obama&quot;</span>
</pre>
</div>
<p>Bindings allow you to architect your application using the MVC (Model-View-Controller)
pattern, then rest easy knowing that data will always flow correctly from layer to layer.</p>
<h4 id='toc_computed-properties'>Computed Properties</h4>
<p>Computed properties allow you to treat a function like a property:</p>
<div class="highlight"><pre><span class="nx">MyApp</span><span class="p">.</span><span class="nx">president</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Barack&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Obama&quot;</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="c1">// Call this flag to mark the function as a property</span>
<span class="p">}.</span><span class="nx">property</span><span class="p">()</span>
<span class="p">});</span>
<span class="nx">MyApp</span><span class="p">.</span><span class="nx">president</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">);</span>
<span class="c1">// &quot;Barack Obama&quot;</span>
</pre>
</div>
<p>Computed properties are useful because they can work with bindings, just
like any other property.</p>
<p>Many computed properties have dependencies on other properties. For example, in the above
example, the <code>fullName</code> property depends on <code>firstName</code> and <code>lastName</code> to determine its value.
You can tell Ember about these dependencies like this:</p>
<div class="highlight"><pre><span class="nx">MyApp</span><span class="p">.</span><span class="nx">president</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Barack&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Obama&quot;</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="c1">// Tell Ember that this computed property depends on firstName</span>
<span class="c1">// and lastName</span>
<span class="p">}.</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s1">&#39;lastName&#39;</span><span class="p">)</span>
<span class="p">});</span>
</pre>
</div>
<p>Make sure you list these dependencies so Ember knows when to update bindings that connect
to a computed property.</p>
<h4 id='toc_auto-updating-templates'>Auto-updating Templates</h4>
<p>Ember uses Handlebars, a semantic templating library. To take data from your JavaScript application
and put it into the DOM, create a <code>&lt;script&gt;</code> tag and put it into your HTML, wherever you&#39;d like the
value to appear:</p>
<div class="highlight"><pre><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/x-handlebars&quot;</span><span class="nt">&gt;</span>
<span class="nx">The</span> <span class="nx">President</span> <span class="nx">of</span> <span class="nx">the</span> <span class="nx">United</span> <span class="nx">States</span> <span class="nx">is</span> <span class="p">{{</span><span class="nx">MyApp</span><span class="p">.</span><span class="nx">president</span><span class="p">.</span><span class="nx">fullName</span><span class="p">}}.</span>
<span class="nt">&lt;/script&gt;</span>
</pre>
</div>
<p>Here&#39;s the best part: templates are bindings-aware. That means that if you ever change the value of
the property that you told us to display, we&#39;ll update it for you automatically. And because you&#39;ve
specified dependencies, changes to <em>those</em> properties are reflected as well.</p>
<p>Hopefully you can see how all three of these powerful tools work together: start with some primitive
properties, then start building up more sophisticated properties and their dependencies using computed
properties. Once you&#39;ve described the data, you only have to say how it gets displayed once, and Ember
takes care of the rest. It doesn&#39;t matter how the underlying data changes, whether from an XHR request
or the user performing an action; your user interface always stays up-to-date. This eliminates entire
categories of edge cases that developers struggle with every day.</p>
</div>
<div class="section" id="object_model">
<h2 id='toc_the-ember-object-model'>The Ember Object Model</h2>
<p>Ember enhances the simple JavaScript object model to support bindings
and observers, as well as to support a more powerful mixin-based
approach to code sharing.</p>
<p>At its most basic, you create a new Ember class by using the <code>extend</code>
method on <code>Ember.Object</code>.</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">say</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="nx">thing</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>Once you have built a new class, you can create new instances of the
class by using the <code>create</code> method. Any properties defined on the class
will be available to instances.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">say</span><span class="p">(</span><span class="s2">&quot;Hello&quot;</span><span class="p">)</span> <span class="c1">// alerts &quot;Hello&quot;</span>
</pre>
</div>
<p>When creating an instance, you can also add additional properties to the
class by passing in an object.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">tom</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Tom Dale&quot;</span><span class="p">,</span>
<span class="nx">helloWorld</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">say</span><span class="p">(</span><span class="s2">&quot;Hi my name is &quot;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">tom</span><span class="p">.</span><span class="nx">helloWorld</span><span class="p">()</span> <span class="c1">// alerts &quot;Hi my name is Tom Dale&quot;</span>
</pre>
</div>
<p>Because of Ember&#39;s support for bindings and observers, you will always
access properties using the <code>get</code> method, and set properties using the
<code>set</code> method.</p>
<p>When creating a new instance of an object, you can also override any
properties or methods defined on the class. For instance, in this case,
you could override the <code>say</code> method from the <code>Person</code> class.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">yehuda</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Yehuda Katz&quot;</span><span class="p">,</span>
<span class="nx">say</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">(</span><span class="nx">name</span> <span class="o">+</span> <span class="s2">&quot; says: &quot;</span> <span class="o">+</span> <span class="nx">thing</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>You can use the <code>_super</code> method on the object (<code>super</code> is a reserved
word in JavaScript) to call the original method you overrode.</p>
<h3 id='toc_subclassing-classes'>Subclassing Classes</h3>
<p>You can also create subclasses of classes you create by using the
<code>extend</code> method. In fact, when we created a new class above by calling
<code>extend</code> on <code>Ember.Object</code>, we were <strong>subclassing</strong> <code>Ember.Object</code>.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">LoudPerson</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">say</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">(</span><span class="nx">thing</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>When subclassing, you can use <code>this._super</code> to invoke methods you are
overriding.</p>
<h3 id='toc_reopening-classes-and-instances'>Reopening Classes and Instances</h3>
<p>You don&#39;t need to define a class all at once. You can reopen a class and
define new properties using the <code>reopen</code> method.</p>
<div class="highlight"><pre><span class="nx">Person</span><span class="p">.</span><span class="nx">reopen</span><span class="p">({</span>
<span class="nx">isPerson</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">().</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;isPerson&#39;</span><span class="p">)</span> <span class="c1">// true</span>
</pre>
</div>
<p>When using <code>reopen</code>, you can also override existing methods and
call <code>this._super</code>.</p>
<div class="highlight"><pre><span class="nx">Person</span><span class="p">.</span><span class="nx">reopen</span><span class="p">({</span>
<span class="c1">// override `say` to add an ! at the end</span>
<span class="nx">say</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_super</span><span class="p">(</span><span class="nx">thing</span> <span class="o">+</span> <span class="s2">&quot;!&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>As you can see, <code>reopen</code> is used to add properties and methods to an instance.
But when you need to create class method or add the properties to the class itself you can use <code>reopenClass</code>.</p>
<div class="highlight"><pre><span class="nx">Person</span><span class="p">.</span><span class="nx">reopenClass</span><span class="p">({</span>
<span class="nx">createMan</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span><span class="nx">isMan</span><span class="o">:</span> <span class="kc">true</span><span class="p">})</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">createMan</span><span class="p">().</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;isMan&#39;</span><span class="p">)</span> <span class="c1">// true</span>
</pre>
</div>
<h3 id='toc_computed-properties-getters'>Computed Properties (Getters)</h3>
<p>Often, you will want a property that is computed based on other
properties. Ember&#39;s object model allows you to define computed
properties easily in a normal class definition.</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="c1">// these will be supplied by `create`</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">;</span>
<span class="p">}.</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s1">&#39;lastName&#39;</span><span class="p">)</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">tom</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Tom&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Dale&quot;</span>
<span class="p">});</span>
<span class="nx">tom</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">)</span> <span class="c1">// &quot;Tom Dale&quot;</span>
</pre>
</div>
<p>If you aren&#39;t using Ember&#39;s prototype extensions, you can use a slightly
more verbose version, wrapping the function in a call to <code>Ember.computed</code>:</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="c1">// these will be supplied by `create`</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">computed</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">;</span>
<span class="p">}).</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s1">&#39;lastName&#39;</span><span class="p">)</span>
<span class="p">});</span>
</pre>
</div>
<p>The <code>property</code> method defines the function as a computed property, and
defines its dependencies. Those dependencies will come into play later
when we discuss bindings and observers.</p>
<p>When subclassing a class or creating a new instance, you can override
any computed properties.</p>
<h3 id='toc_computed-properties-setters'>Computed Properties (Setters)</h3>
<p>You can also define what Ember should do when setting a computed
property. If you try to set a computed property, it will be invoked with
the key and value you want to set it to.</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="c1">// these will be supplied by `create`</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">computed</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// getter</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">;</span>
<span class="c1">// setter</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">value</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="nx">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">,</span> <span class="nx">name</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="k">return</span> <span class="nx">value</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}).</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s1">&#39;lastName&#39;</span><span class="p">)</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">,</span> <span class="s2">&quot;Peter Wagenet&quot;</span><span class="p">);</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">)</span> <span class="c1">// Peter</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">)</span> <span class="c1">// Wagenet</span>
</pre>
</div>
<p>Ember will call the computed property for both setters and getters, and
you can check the number of arguments to determine whether it is being called
as a getter or a setter.</p>
<h3 id='toc_observers'>Observers</h3>
<p>Ember supports observing any property, including computed properties.
You can set up an observer on an object by using the <code>addObserver</code>
method.</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="c1">// these will be supplied by `create`</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">computed</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastName&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="s1">&#39; &#39;</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">;</span>
<span class="p">}).</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s1">&#39;lastName&#39;</span><span class="p">)</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">person</span> <span class="o">=</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Yehuda&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Katz&quot;</span>
<span class="p">});</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">addObserver</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// deal with the change</span>
<span class="p">});</span>
<span class="nx">person</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;firstName&#39;</span><span class="p">,</span> <span class="s2">&quot;Brohuda&quot;</span><span class="p">);</span> <span class="c1">// observer will fire</span>
</pre>
</div>
<p>Because the <code>fullName</code> computed property depends on <code>firstName</code>,
updating <code>firstName</code> will fire observers on <code>fullName</code> as well.</p>
<p>Because observers are so common, Ember provides a way to define
observers inline in class definitions.</p>
<div class="highlight"><pre><span class="nx">Person</span><span class="p">.</span><span class="nx">reopen</span><span class="p">({</span>
<span class="nx">fullNameChanged</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// this is an inline version of .addObserver</span>
<span class="p">}.</span><span class="nx">observes</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">)</span>
<span class="p">});</span>
</pre>
</div>
<p>You can define inline observers by using the <code>Ember.observer</code> method if you
are using Ember without prototype extensions:</p>
<div class="highlight"><pre><span class="nx">Person</span><span class="p">.</span><span class="nx">reopen</span><span class="p">({</span>
<span class="nx">fullNameChanged</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">observer</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// this is an inline version of .addObserver</span>
<span class="p">},</span> <span class="s1">&#39;fullName&#39;</span><span class="p">)</span>
<span class="p">});</span>
</pre>
</div>
<h4 id='toc_changes-in-arrays'>Changes in Arrays</h4>
<p>Often, you may have a computed property that relies on all of the items in an
array to determine its value. For example, you may want to count all of the
todo items in a controller to determine how many of them are completed.</p>
<p>Here&#39;s what that computed property might look like:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">todosController</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">todos</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">isDone</span><span class="o">:</span> <span class="kc">false</span> <span class="p">})</span>
<span class="p">],</span>
<span class="nx">remaining</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">todos</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;todos&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">todos</span><span class="p">.</span><span class="nx">filterProperty</span><span class="p">(</span><span class="s1">&#39;isDone&#39;</span><span class="p">,</span> <span class="kc">false</span><span class="p">).</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;length&#39;</span><span class="p">);</span>
<span class="p">}.</span><span class="nx">property</span><span class="p">(</span><span class="s1">&#39;todos.@each.isDone&#39;</span><span class="p">)</span>
<span class="p">});</span>
</pre>
</div>
<p>Note here that the dependent key (<code>todos.@each.isDone</code>) contains the special
key <code>@each</code>. This instructs Ember.js to update bindings and fire observers for
this computed property when one of the following four events occurs:</p>
<ol>
<li>The <code>isDone</code> property of any of the objects in the <code>todos</code> array changes.</li>
<li>An item is added to the <code>todos</code> array.</li>
<li>An item is removed from the <code>todos</code> array.</li>
<li>The <code>todos</code> property of the controller is changed to a different array.</li>
</ol>
<p>In the example above, the <code>remaining</code> count is <code>1</code>:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">todosController</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;remaining&#39;</span><span class="p">);</span>
<span class="c1">// 1</span>
</pre>
</div>
<p>If we change the todo&#39;s <code>isDone</code> property, the <code>remaining</code> property is updated
automatically:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">todos</span> <span class="o">=</span> <span class="nx">App</span><span class="p">.</span><span class="nx">todosController</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;todos&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">todo</span> <span class="o">=</span> <span class="nx">todos</span><span class="p">.</span><span class="nx">objectAt</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="nx">todo</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;isDone&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">todosController</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;remaining&#39;</span><span class="p">);</span>
<span class="c1">// 0</span>
<span class="nx">todo</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">isDone</span><span class="o">:</span> <span class="kc">false</span> <span class="p">});</span>
<span class="nx">todos</span><span class="p">.</span><span class="nx">pushObject</span><span class="p">(</span><span class="nx">todo</span><span class="p">);</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">todosController</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;remaining&#39;</span><span class="p">);</span>
<span class="c1">// 1</span>
</pre>
</div>
<h3 id='toc_bindings'>Bindings</h3>
<p>A binding creates a link between two properties such that when one changes, the
other one is updated to the new value automatically. Bindings can connect
properties on the same object, or across two different objects. Unlike most other
frameworks that include some sort of binding implementation, bindings in
Ember.js can be used with any object, not just between views and models.</p>
<p>The easiest way to create a two-way binding is by creating a new property
with the string <code>Binding</code> at the end, then specifying a path from the global scope:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">wife</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">householdIncome</span><span class="o">:</span> <span class="mi">80000</span>
<span class="p">});</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">husband</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">householdIncomeBinding</span><span class="o">:</span> <span class="s1">&#39;App.wife.householdIncome&#39;</span>
<span class="p">});</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">husband</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;householdIncome&#39;</span><span class="p">);</span> <span class="c1">// 80000</span>
<span class="c1">// Someone gets raise.</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">husband</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;householdIncome&#39;</span><span class="p">,</span> <span class="mi">90000</span><span class="p">);</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">wife</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;householdIncome&#39;</span><span class="p">);</span> <span class="c1">// 90000</span>
</pre>
</div>
<p>Note that bindings don&#39;t update immediately. Ember waits until all of your
application code has finished running before synchronizing changes, so you can
change a bound property as many times as you&#39;d like without worrying about the
overhead of syncing bindings when values are transient.</p>
<h4 id='toc_one-way-bindings'>One-Way Bindings</h4>
<p>A one-way binding only propagates changes in one direction. Usually, one-way
bindings are just a performance optimization and you can safely use
the more concise two-way binding syntax (as, of course, two-way bindings are
de facto one-way bindings if you only ever change one side).</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="s2">&quot;Kara Gates&quot;</span>
<span class="p">});</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">userView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">userNameBinding</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">Binding</span><span class="p">.</span><span class="nx">oneWay</span><span class="p">(</span><span class="s1">&#39;App.user.fullName&#39;</span><span class="p">)</span>
<span class="p">});</span>
<span class="c1">// Changing the name of the user object changes</span>
<span class="c1">// the value on the view.</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">,</span> <span class="s2">&quot;Krang Gates&quot;</span><span class="p">);</span>
<span class="c1">// App.userView.userName will become &quot;Krang Gates&quot;</span>
<span class="c1">// ...but changes to the view don&#39;t make it back to</span>
<span class="c1">// the object.</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">userView</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;userName&#39;</span><span class="p">,</span> <span class="s2">&quot;Truckasaurus Gates&quot;</span><span class="p">);</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;fullName&#39;</span><span class="p">);</span> <span class="c1">// &quot;Krang Gates&quot;</span>
</pre>
</div>
<h3 id='toc_what-do-i-use-when'>What Do I Use When?</h3>
<p>Sometimes new users are confused about when to use computed properties,
bindings and observers. Here are some guidelines to help:</p>
<ol>
<li><p>Use <em>computed properties</em> to build a new property by synthesizing other
properties. Computed properties should not contain application behavior, and
should generally not cause any side-effects when called. Except in rare cases,
multiple calls to the same computed property should always return the same
value (unless the properties it depends on have changed, of course.)</p></li>
<li><p><em>Observers</em> should contain behavior that reacts to changes in another
property. Observers are especially useful when you need to perform some
behavior after a binding has finished synchronizing.</p></li>
<li><p><em>Bindings</em> are most often used to ensure objects in two different layers
are always in sync. For example, you bind your views to your controller using
Handlebars. You may often bind between two objects in the same layer. For
example, you might have an <code>App.selectedContactController</code> that binds to the
<code>selectedContact</code> property of <code>App.contactsController</code>.</p></li>
</ol>
</div>
<div class="section" id="application">
<h2 id='toc_creating-a-namespace'>Creating a Namespace</h2>
<p>Every Ember app should have an instance of <code>Ember.Application</code>. This object
will serve as the globally-accessible namespace for all of the other classes
and instances in your app. Additionally, it sets up event listeners on the page
so that your views receive events when users interact with your user interface
(which you&#39;ll learn about later.)</p>
<p>Here&#39;s an example of an application:</p>
<div class="highlight"><pre><span class="nb">window</span><span class="p">.</span><span class="nx">App</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">Application</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
</pre>
</div>
<p>You can call your namespace whatever you&#39;d like, but it must begin
with a capital letter in order for bindings to find it.</p>
<p>If you are embedding an Ember application into an existing site, you can
have event listeners set up for a specific element by providing a <code>rootElement</code> property:</p>
<div class="highlight"><pre><span class="nb">window</span><span class="p">.</span><span class="nx">App</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">Application</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">rootElement</span><span class="o">:</span> <span class="s1">&#39;#sidebar&#39;</span>
<span class="p">});</span>
</pre>
</div>
</div>
<div class="section" id="handlebars">
<h2 id='toc_describing-your-ui-with-handlebars'>Describing Your UI with Handlebars</h2><h3 id='toc_handlebars'>Handlebars</h3>
<p>Ember comes bundled with <a href="http://www.handlebarsjs.com">Handlebars</a>, a semantic templating language. These templates look like regular HTML, with embedded expressions.</p>
<p>You should store your Handlebars templates inside your application&#39;s HTML file. At runtime, Ember will compile these templates so they are available for you to use in your views.</p>
<p>To immediately insert a template into your document, place it inside a <code>&lt;script&gt;</code> tag within your <code>&lt;body&gt;</code> tag:</p>
<div class="highlight"><pre><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/x-handlebars&quot;</span><span class="nt">&gt;</span>
<span class="nx">Hello</span><span class="p">,</span> <span class="o">&lt;</span><span class="nx">b</span><span class="o">&gt;</span><span class="p">{{</span><span class="nx">MyApp</span><span class="p">.</span><span class="nx">name</span><span class="p">}}</span><span class="o">&lt;</span><span class="err">/b&gt;</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre>
</div>
<p>To make a template available to be used later, give the <code>&lt;script&gt;</code> tag a <code>data-template-name</code> attribute:</p>
<div class="highlight"><pre><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/x-handlebars&quot;</span> <span class="na">data-template-name=</span><span class="s">&quot;say-hello&quot;</span><span class="nt">&gt;</span>
<span class="nx">Hello</span><span class="p">,</span> <span class="o">&lt;</span><span class="nx">b</span><span class="o">&gt;</span><span class="p">{{</span><span class="nx">MyApp</span><span class="p">.</span><span class="nx">name</span><span class="p">}}</span><span class="o">&lt;</span><span class="err">/b&gt;</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre>
</div>
<h3 id='toc_ember-view'>Ember.View</h3>
<p>You can use <code>Ember.View</code> to render a Handlebars template and insert it into the DOM.</p>
<p>To tell the view which template to use, set its <code>templateName</code> property. For example, if I had a <code>&lt;script&gt;</code> tag like this:</p>
<div class="highlight"><pre><span class="nt">&lt;html&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/x-handlebars&quot;</span> <span class="na">data-template-name=</span><span class="s">&quot;say-hello&quot;</span><span class="nt">&gt;</span>
<span class="nx">Hello</span><span class="p">,</span> <span class="o">&lt;</span><span class="nx">b</span><span class="o">&gt;</span><span class="p">{{</span><span class="nx">name</span><span class="p">}}</span><span class="o">&lt;</span><span class="err">/b&gt;</span>
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</pre>
</div>
<p>I would set the <code>templateName</code> property to <code>&quot;say-hello&quot;</code>.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">view</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;say-hello&#39;</span><span class="p">,</span>
<span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Bob&quot;</span>
<span class="p">});</span>
</pre>
</div>
<p>Note: For the remainder of the guide, the <code>templateName</code> property will be omitted from most examples. You can assume that if we show a code sample that includes an Ember.View and a Handlebars template, the view has been configured to display that template via the <code>templateName</code> property.</p>
<p>You can append views to the document by calling <code>appendTo</code>:</p>
<div class="highlight"><pre> <span class="nx">view</span><span class="p">.</span><span class="nx">appendTo</span><span class="p">(</span><span class="s1">&#39;#container&#39;</span><span class="p">);</span>
</pre>
</div>
<p>As a shorthand, you can append a view to the document body by calling <code>append</code>:</p>
<div class="highlight"><pre> <span class="nx">view</span><span class="p">.</span><span class="nx">append</span><span class="p">();</span>
</pre>
</div>
<p>To remove a view from the document, call <code>remove</code>:</p>
<div class="highlight"><pre> <span class="nx">view</span><span class="p">.</span><span class="nx">remove</span><span class="p">();</span>
</pre>
</div>
<h3 id='toc_handlebars-basics'>Handlebars Basics</h3>
<p>As you&#39;ve already seen, you can print the value of a property by enclosing it in a Handlebars expression, or a series of braces, like this:</p>
<div class="highlight"><pre>My new car is {{color}}.
</pre>
</div>
<p>This will look up and print the View&#39;s <code>color</code> property. For example, if your view looks like this:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">CarView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">color</span><span class="o">:</span> <span class="s1">&#39;blue&#39;</span>
<span class="p">});</span>
</pre>
</div>
<p>Your view would appear in the browser like this:</p>
<div class="highlight"><pre>My new car is blue.
</pre>
</div>
<p>You can also specify global paths:</p>
<div class="highlight"><pre>My new car is {{App.carController.color}}.
</pre>
</div>
<p>(Ember determines whether a path is global or relative to the view by checking whether the first letter is capitalized,
which is why your <code>Ember.Application</code> instance should start with a capital letter.)</p>
<p>All of the features described in this guide are <strong>bindings aware</strong>. That means that if the values used by your templates ever change, your HTML will be updated automatically. It&#39;s like magic.</p>
<p>In order to know which part of your HTML to update when an underlying property changes, Handlebars will insert marker elements with a unique ID. If you look at your application while it&#39;s running, you might notice these extra elements:</p>
<div class="highlight"><pre>My new car is
<span class="nt">&lt;script </span><span class="na">id=</span><span class="s">&quot;metamorph-0-start&quot;</span> <span class="na">type=</span><span class="s">&quot;text/x-placeholder&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>
blue
<span class="nt">&lt;script </span><span class="na">id=</span><span class="s">&quot;metamorph-0-end&quot;</span> <span class="na">type=</span><span class="s">&quot;text/x-placeholder&quot;</span><span class="nt">&gt;&lt;/script&gt;</span>.
</pre>
</div>
<p>Because all Handlebars expressions are wrapped in these markers, make sure each HTML tag stays inside the same block. For example, you shouldn&#39;t do this:</p>
<div class="highlight"><pre><span class="c">&lt;!-- Don&#39;t do it! --&gt;</span>
<span class="nt">&lt;div</span> <span class="err">{{#</span><span class="na">if</span> <span class="na">isUrgent</span><span class="err">}}</span><span class="na">class=</span><span class="s">&quot;urgent&quot;</span><span class="err">{{/</span><span class="na">if</span><span class="err">}}</span><span class="nt">&gt;</span>
</pre>
</div>
<p>If you want to avoid your property output getting wrapped in these markers, use the <code>unbound</code> helper:</p>
<div class="highlight"><pre>My new car is {{unbound color}}.
</pre>
</div>
<p>Your output will be free of markers, but be careful, because the output won&#39;t be automatically updated!</p>
<div class="highlight"><pre>My new car is blue.
</pre>
</div>
<h3 id='toc_if-else-and-unless'>{{#if}}, {{else}}, and {{#unless}}</h3>
<p>Sometimes you may only want to display part of your template if a property
exists. For example, let&#39;s say we have a view with a <code>person</code> property that
contains an object with <code>firstName</code> and <code>lastName</code> fields:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">SayHelloView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">person</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Joy&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Clojure&quot;</span>
<span class="p">})</span>
<span class="p">});</span>
</pre>
</div>
<p>In order to display part of the template only if the <code>person</code> object exists, we
can use the <code>{{#if}}</code> helper to conditionally render a block:</p>
<div class="highlight"><pre>{{#if person}}
Welcome back, <span class="nt">&lt;b&gt;</span>{{person.firstName}} {{person.lastName}}<span class="nt">&lt;/b&gt;</span>!
{{/if}}
</pre>
</div>
<p>Handlebars will not render the block if the argument passed evaluates to
<code>false</code>, <code>undefined</code>, <code>null</code> or <code>[]</code> (i.e., any &quot;falsy&quot; value).</p>
<p>If the expression evaluates to falsy, we can also display an alternate template
using <code>{{else}}</code>:</p>
<div class="highlight"><pre>{{#if person}}
Welcome back, <span class="nt">&lt;b&gt;</span>{{person.firstName}} {{person.lastName}}<span class="nt">&lt;/b&gt;</span>!
{{else}}
Please log in.
{{/if}}
</pre>
</div>
<p>To only render a block if a value is falsy, use <code>{{#unless}}</code>:</p>
<div class="highlight"><pre>{{#unless hasPaid}}
You owe: ${{total}}
{{/unless}}
</pre>
</div>
<p><code>{{#if}}</code> and <code>{{#unless}}</code> are examples of block expressions. These allow you
to invoke a helper with a portion of your template. Block expressions look like
normal expressions except that they contain a hash (#) before the helper name,
and require a closing expression.</p>
<h3 id='toc_with'>{{#with}}</h3>
<p>Sometimes you may want to invoke a section of your template with a context
different than the Ember.View. For example, we can clean up the above template by
using the <code>{{#with}}</code> helper:</p>
<div class="highlight"><pre>{{#with person}}
Welcome back, <span class="nt">&lt;b&gt;</span>{{firstName}} {{lastName}}<span class="nt">&lt;/b&gt;</span>!
{{/with}}
</pre>
</div>
<p><code>{{#with}}</code> changes the <em>context</em> of the block you pass to it. The context
is the object on which properties are looked up. By default, the context is the
Ember.View to which the template belongs.</p>
<h3 id='toc_binding-element-attributes-with-bindattr'>Binding Element Attributes with {{bindAttr}}</h3>
<p>In addition to text, you may also want your templates to dictate the attributes
of your HTML elements. For example, imagine a view that contains a URL:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">LogoView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">logoUrl</span><span class="o">:</span> <span class="s1">&#39;http://www.mycorp.com/images/logo.png&#39;</span>
<span class="p">});</span>
</pre>
</div>
<p>The best way to display the URL as an image in Handlebars is like this:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;logo&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;img</span> <span class="err">{{</span><span class="na">bindAttr</span> <span class="na">src=</span><span class="s">&quot;logoUrl&quot;</span><span class="err">}}</span> <span class="na">alt=</span><span class="s">&quot;Logo&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>This generates the following HTML:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;logo&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">&quot;http://www.mycorp.com/images/logo.png&quot;</span> <span class="na">alt=</span><span class="s">&quot;Logo&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>If you use <code>{{bindAttr}}</code> with a Boolean value, it will add or remove the specified attribute. For example, given this Ember view:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">InputView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">isDisabled</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre>
</div>
<p>And this template:</p>
<div class="highlight"><pre><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;checkbox&quot;</span> <span class="err">{{</span><span class="na">bindAttr</span> <span class="na">disabled=</span><span class="s">&quot;isDisabled&quot;</span><span class="err">}}</span><span class="nt">&gt;</span>
</pre>
</div>
<p>Handlebars will produce the following HTML element:</p>
<div class="highlight"><pre><span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">&quot;checkbox&quot;</span> <span class="na">disabled</span><span class="nt">&gt;</span>
</pre>
</div>
<h3 id='toc_binding-class-names-with-bindattr'>Binding Class Names with {{bindAttr}}</h3>
<p>The <code>class</code> attribute can be bound like any other attribute, but it also has some additional special behavior. The default behavior works like you&#39;d expect:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">AlertView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">priority</span><span class="o">:</span> <span class="s2">&quot;p4&quot;</span><span class="p">,</span>
<span class="nx">isUrgent</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="err">{{</span><span class="na">bindAttr</span> <span class="na">class=</span><span class="s">&quot;priority&quot;</span><span class="err">}}</span><span class="nt">&gt;</span>
Warning!
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>This template will emit the following HTML:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;p4&quot;</span><span class="nt">&gt;</span>
Warning!
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>If the value to which you bind is a Boolean, however, the dasherized version of that property will be applied as a class:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="err">{{</span><span class="na">bindAttr</span> <span class="na">class=</span><span class="s">&quot;isUrgent&quot;</span><span class="err">}}</span><span class="nt">&gt;</span>
Warning!
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>This emits the following HTML:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;is-urgent&quot;</span><span class="nt">&gt;</span>
Warning!
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<p>Unlike other attributes, you can also bind multiple classes:</p>
<div class="highlight"><pre><span class="o">&lt;</span><span class="nx">div</span> <span class="p">{{</span><span class="nx">bindAttr</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;isUrgent priority&quot;</span><span class="p">}}</span><span class="o">&gt;</span>
<span class="nx">Warning</span><span class="o">!</span>
<span class="o">&lt;</span><span class="err">/div&gt;</span>
</pre>
</div>
<p>You can also specify an alternate class name to use, instead of just
dasherizing.</p>
<div class="highlight"><pre><span class="o">&lt;</span><span class="nx">div</span> <span class="p">{{</span><span class="nx">bindAttr</span> <span class="kr">class</span><span class="o">=</span><span class="s2">&quot;isUrgent:urgent&quot;</span><span class="p">}}</span><span class="o">&gt;</span>
<span class="nx">Warning</span><span class="o">!</span>
<span class="o">&lt;</span><span class="err">/div&gt;</span>
</pre>
</div>
<p>In this case, if the <code>isUrgent</code> property is true, the <code>urgent</code> class
will be added. If it is false, the <code>urgent</code> class will be removed.</p>
<h3 id='toc_handling-events-with-action'>Handling Events with {{action}}</h3>
<p>Use the <code>{{action}}</code> helper to attach a handler in your view class to an event triggered on an element.</p>
<p>To attach an element&#39;s <code>click</code> event to the <code>edit()</code> handler in the current view:</p>
<div class="highlight"><pre><span class="o">&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="s2">&quot;#&quot;</span> <span class="p">{{</span><span class="nx">action</span> <span class="s2">&quot;edit&quot;</span> <span class="nx">on</span><span class="o">=</span><span class="s2">&quot;click&quot;</span><span class="p">}}</span><span class="o">&gt;</span><span class="nx">Edit</span><span class="o">&lt;</span><span class="err">/a&gt;</span>
</pre>
</div>
<p>Because the default event is <code>click</code>, this could be written more concisely as:</p>
<div class="highlight"><pre><span class="o">&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="s2">&quot;#&quot;</span> <span class="p">{{</span><span class="nx">action</span> <span class="s2">&quot;edit&quot;</span><span class="p">}}</span><span class="o">&gt;</span><span class="nx">Edit</span><span class="o">&lt;</span><span class="err">/a&gt;</span>
</pre>
</div>
<p>Although the view containing the <code>{{action}}</code> helper will be targeted by default, it is possible to target a different view:</p>
<div class="highlight"><pre><span class="o">&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="s2">&quot;#&quot;</span> <span class="p">{{</span><span class="nx">action</span> <span class="s2">&quot;edit&quot;</span> <span class="nx">target</span><span class="o">=</span><span class="s2">&quot;parentView&quot;</span><span class="p">}}</span><span class="o">&gt;</span><span class="nx">Edit</span><span class="o">&lt;</span><span class="err">/a&gt;</span>
</pre>
</div>
<p>The action handler can optionally accept a jQuery event object, which will be extended to include <code>view</code> and <code>context</code> properties. These properties can be useful when targeting a different view with your action. For instance:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">ListingView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;listing&#39;</span><span class="p">,</span>
<span class="nx">edit</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">view</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;isEditing&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>Any of the templates discussed above will produce an HTML element like this:</p>
<div class="highlight"><pre><span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;#&quot;</span> <span class="na">data-ember-action=</span><span class="s">&quot;3&quot;</span><span class="nt">&gt;</span>Edit<span class="nt">&lt;/a&gt;</span>
</pre>
</div>
<p>Ember will delegate the event you specified to your target view&#39;s handler based upon the internally assigned <code>data-ember-action</code> id.</p>
<h3 id='toc_building-a-view-hierarchy'>Building a View Hierarchy</h3>
<p>So far, we&#39;ve discussed writing templates for a single view. However, as your application grows, you will often want to create a hierarchy of views to encapsulate different areas on the page. Each view is responsible for handling events and maintaining the properties needed to display it.</p>
<h3 id='toc_view'>{{view}}</h3>
<p>To add a child view to a parent, use the <code>{{view}}</code> helper, which takes a path to a view class.</p>
<div class="highlight"><pre><span class="c1">// Define parent view</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">UserView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Albert&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Hofmann&quot;</span>
<span class="p">});</span>
<span class="c1">// Define child view</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">InfoView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;info&#39;</span><span class="p">,</span>
<span class="nx">posts</span><span class="o">:</span> <span class="mi">25</span><span class="p">,</span>
<span class="nx">hobbies</span><span class="o">:</span> <span class="s2">&quot;Riding bicycles&quot;</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre>User: {{firstName}} {{lastName}}
{{view App.InfoView}}
</pre>
</div>
<div class="highlight"><pre><span class="nt">&lt;b&gt;</span>Posts:<span class="nt">&lt;/b&gt;</span> {{posts}}
<span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;b&gt;</span>Hobbies:<span class="nt">&lt;/b&gt;</span> {{hobbies}}
</pre>
</div>
<p>If we were to create an instance of <code>App.UserView</code> and render it, we would get
a DOM representation like this:</p>
<div class="highlight"><pre>User: Albert Hofmann
<span class="nt">&lt;div&gt;</span>
<span class="nt">&lt;b&gt;</span>Posts:<span class="nt">&lt;/b&gt;</span> 25
<span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;b&gt;</span>Hobbies:<span class="nt">&lt;/b&gt;</span> Riding bicycles
<span class="nt">&lt;/div&gt;</span>
</pre>
</div>
<h4 id='toc_relative-paths'>Relative Paths</h4>
<p>Instead of specifying an absolute path, you can also specify which view class
to use relative to the parent view. For example, we could nest the above view
hierarchy like this:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">UserView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Albert&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Hofmann&quot;</span><span class="p">,</span>
<span class="nx">infoView</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;info&#39;</span><span class="p">,</span>
<span class="nx">posts</span><span class="o">:</span> <span class="mi">25</span><span class="p">,</span>
<span class="nx">hobbies</span><span class="o">:</span> <span class="s2">&quot;Riding bicycles&quot;</span>
<span class="p">})</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre>User: {{firstName}} {{lastName}}
{{view infoView}}
</pre>
</div>
<p>When nesting a view class like this, make sure to use a lowercase
letter, as Ember will interpret a property with a capital letter as a
global property.</p>
<h3 id='toc_setting-child-view-templates'>Setting Child View Templates</h3>
<p>If you&#39;d like to specify the template your child views use inline in
the main template, you can use the block form of the <code>{{view}}</code> helper.
We might rewrite the above example like this:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">UserView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Albert&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Hofmann&quot;</span>
<span class="p">});</span>
<span class="nx">App</span><span class="p">.</span><span class="nx">InfoView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">posts</span><span class="o">:</span> <span class="mi">25</span><span class="p">,</span>
<span class="nx">hobbies</span><span class="o">:</span> <span class="s2">&quot;Riding bicycles&quot;</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre>User: {{firstName}} {{lastName}}
{{#view App.InfoView}}
<span class="nt">&lt;b&gt;</span>Posts:<span class="nt">&lt;/b&gt;</span> {{posts}}
<span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;b&gt;</span>Hobbies:<span class="nt">&lt;/b&gt;</span> {{hobbies}}
{{/view}}
</pre>
</div>
<p>When you do this, it may be helpful to think of it as assigning views to
portions of the page. This allows you to encapsulate event handling for just
that part of the page.</p>
<h3 id='toc_setting-up-bindings'>Setting Up Bindings</h3>
<p>So far in our examples, we have been setting static values directly on the
views. But to best implement an MVC architecture, we should actually be binding
the properties of our views to the controller layer.</p>
<p>Let&#39;s set up a controller to represent our user data:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">userController</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">content</span><span class="o">:</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Albert&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Hofmann&quot;</span><span class="p">,</span>
<span class="nx">posts</span><span class="o">:</span> <span class="mi">25</span><span class="p">,</span>
<span class="nx">hobbies</span><span class="o">:</span> <span class="s2">&quot;Riding bicycles&quot;</span>
<span class="p">})</span>
<span class="p">});</span>
</pre>
</div>
<p>Now let&#39;s update <code>App.UserView</code> to bind to <code>App.userController</code>:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">UserView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">templateName</span><span class="o">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
<span class="nx">firstNameBinding</span><span class="o">:</span> <span class="s1">&#39;App.userController.content.firstName&#39;</span><span class="p">,</span>
<span class="nx">lastNameBinding</span><span class="o">:</span> <span class="s1">&#39;App.userController.content.lastName&#39;</span>
<span class="p">});</span>
</pre>
</div>
<p>When we only have a few bindings to configure, like with <code>App.UserView</code>, it is
sometimes useful to be able to declare those bindings in the template. You can
do that by passing additional arguments to the <code>{{#view}}</code> helper. If all
you&#39;re doing is configuring bindings, this often allows you to bypass having to
create a new subclass.</p>
<div class="highlight"><pre>User: {{firstName}} {{lastName}}
{{#view App.UserView postsBinding=&quot;App.userController.content.posts&quot;
hobbiesBinding=&quot;App.userController.content.hobbies&quot;}}
<span class="nt">&lt;b&gt;</span>Posts:<span class="nt">&lt;/b&gt;</span> {{posts}}
<span class="nt">&lt;br&gt;</span>
<span class="nt">&lt;b&gt;</span>Hobbies:<span class="nt">&lt;/b&gt;</span> {{hobbies}}
{{/view}}
</pre>
</div>
<p>NOTE: You can actually pass <strong>any</strong> property as a parameter to {{view}}, not
just bindings. However, if you are doing anything other than setting up
bindings, it is generally a good idea to create a new subclass.</p>
<h3 id='toc_modifying-a-view-s-html'>Modifying a View&#39;s HTML</h3>
<p>When you append a view, it creates a new HTML element that holds its content.
If your view has any child views, they will also be displayed as child nodes
of the parent&#39;s HTML element.</p>
<p>By default, new instances of <code>Ember.View</code> create a <code>&lt;div&gt;</code> element. You can
override this by passing a <code>tagName</code> parameter:</p>
<div class="highlight"><pre>{{view App.InfoView tagName=&quot;span&quot;}}
</pre>
</div>
<p>You can also assign an ID attribute to the view&#39;s HTML element by passing an <code>id</code> parameter:</p>
<div class="highlight"><pre>{{view App.InfoView id=&quot;info-view&quot;}}
</pre>
</div>
<p>This makes it easy to style using CSS ID selectors:</p>
<div class="highlight"><pre><span class="c">/** Give the view a red background. **/</span>
<span class="nf">#info-view</span> <span class="p">{</span>
<span class="k">background-color</span><span class="o">:</span> <span class="nb">red</span><span class="p">;</span>
<span class="p">}</span>
</pre>
</div>
<p>You can assign class names similarly:</p>
<div class="highlight"><pre>{{view App.InfoView class=&quot;info urgent&quot;}}
</pre>
</div>
<p>You can bind class names to a property of the view by using <code>classBinding</code> instead of <code>class</code>. The same behavior as described in <code>bindAttr</code> applies:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">AlertView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">priority</span><span class="o">:</span> <span class="s2">&quot;p4&quot;</span><span class="p">,</span>
<span class="nx">isUrgent</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre>{{view App.AlertView classBinding=&quot;isUrgent priority&quot;}}
</pre>
</div>
<p>This yields a view wrapper that will look something like this:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;sc420&quot;</span> <span class="na">class=</span><span class="s">&quot;sc-view is-urgent p4&quot;</span><span class="nt">&gt;&lt;/div&gt;</span>
</pre>
</div>
<h3 id='toc_displaying-a-list-of-items'>Displaying a List of Items</h3>
<p>If you need to enumerate over a list of objects, use Handlebar&#39;s <code>{{#each}}</code> helper:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">PeopleView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">people</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Yehuda&#39;</span> <span class="p">},</span>
<span class="p">{</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Tom&#39;</span> <span class="p">}</span> <span class="p">]</span>
<span class="p">});</span>
</pre>
</div>
<div class="highlight"><pre><span class="nt">&lt;ul&gt;</span>
{{#each people}}
<span class="nt">&lt;li&gt;</span>Hello, {{name}}!<span class="nt">&lt;/li&gt;</span>
{{/each}}
<span class="nt">&lt;/ul&gt;</span>
</pre>
</div>
<p>This will print a list like this:</p>
<div class="highlight"><pre><span class="nt">&lt;ul&gt;</span>
<span class="nt">&lt;li&gt;</span>Hello, Yehuda!<span class="nt">&lt;/li&gt;</span>
<span class="nt">&lt;li&gt;</span>Hello, Tom!<span class="nt">&lt;/li&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
</pre>
</div>
<p>If you want to create a view for every item in a list, you can bind a property of the view to
the current context. For example, this example creates a view for every item in a list and sets
the <code>content</code> property to that item:</p>
<div class="highlight"><pre>{{#each App.peopleController}}
{{#view App.PersonView contentBinding=&quot;this&quot;}}
{{content.firstName}} {{content.lastName}}
{{/view}}
{{/each}}
</pre>
</div>
<h3 id='toc_writing-custom-helpers'>Writing Custom Helpers</h3>
<p>Sometimes, you may use the same HTML in your application multiple times. In those case, you can register a custom helper that can be invoked from any Handlebars template.</p>
<p>For example, imagine you are frequently wrapping certain values in a <code>&lt;span&gt;</code> tag with a custom class. You can register a helper from your JavaScript like this:</p>
<div class="highlight"><pre><span class="nx">Handlebars</span><span class="p">.</span><span class="nx">registerHelper</span><span class="p">(</span><span class="s1">&#39;highlight&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">property</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">getPath</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">property</span><span class="p">);</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Handlebars</span><span class="p">.</span><span class="nx">SafeString</span><span class="p">(</span><span class="s1">&#39;&lt;span class=&quot;highlight&quot;&gt;&#39;</span><span class="o">+</span><span class="nx">value</span><span class="o">+</span><span class="s1">&#39;&lt;/span&gt;&#39;</span><span class="p">);</span>
<span class="p">});</span>
</pre>
</div>
<p>If you return HTML from a helper, and you don&#39;t want it to be escaped,
make sure to return a new <code>SafeString</code>.</p>
<p>Anywhere in your Handlebars templates, you can now invoke this helper:</p>
<div class="highlight"><pre>{{highlight name}}
</pre>
</div>
<p>and it will output the following:</p>
<div class="highlight"><pre><span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;highlight&quot;</span><span class="nt">&gt;</span>Peter<span class="nt">&lt;/span&gt;</span>
</pre>
</div>
<p>NOTE: Parameters to helper functions are passed as names, not their current values. This allows you to optionally set up observers on the values. To get the current value of the parameter, use Ember.getPath, as shown above.</p>
<h3 id='toc_included-views'>Included Views</h3>
<p>Ember comes pre-packaged with a set of views for building a few basic controls like text inputs, check boxes, and select lists.</p>
<p>They are:</p>
<h4 id='toc_ember-button'>Ember.Button</h4><div class="highlight"><pre> <span class="kd">var</span> <span class="nx">button</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">Button</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">target</span><span class="o">:</span> <span class="s1">&#39;MyApp.myActionObject&#39;</span><span class="p">,</span>
<span class="nx">action</span><span class="o">:</span> <span class="s1">&#39;myAction&#39;</span>
<span class="p">});</span>
</pre>
</div>
<h4 id='toc_ember-checkbox'>Ember.Checkbox</h4><div class="highlight"><pre> {{view Ember.Checkbox titleBinding=&quot;content.title&quot; valueBinding=&quot;content.isDone&quot;}}
</pre>
</div>
<h4 id='toc_ember-textfield'>Ember.TextField</h4><div class="highlight"><pre> <span class="nx">App</span><span class="p">.</span><span class="nx">myText</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">TextField</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">formBlurredBinding</span><span class="o">:</span> <span class="s1">&#39;App.adminController.formBlurred&#39;</span><span class="p">,</span>
<span class="nx">change</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">evt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;formBlurred&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<h4 id='toc_ember-select'>Ember.Select</h4><div class="highlight"><pre> {{view Ember.Select viewName=&quot;select&quot;
contentBinding=&quot;app.peopleController&quot;
optionLabelPath=&quot;content.fullName&quot;
optionValuePath=&quot;content.id&quot;
prompt=&quot;Pick a person:&quot;
selectionBinding=&quot;app.selectedPersonController.person&quot;}}
</pre>
</div>
<h4 id='toc_ember-textarea'>Ember.TextArea</h4><div class="highlight"><pre> <span class="kd">var</span> <span class="nx">textArea</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">TextArea</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">valueBinding</span><span class="o">:</span> <span class="s1">&#39;TestObject.value&#39;</span>
<span class="p">});</span>
</pre>
</div>
<p>If you would like to add one of these controls to your view, you are encouraged to extend from these controls.</p>
<p>Events do not bubble from a subview to a parent view so extending these views is the only way to capture those events.</p>
<p>Example:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">myText</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">TextField</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">formBlurredBinding</span><span class="o">:</span> <span class="s1">&#39;App.adminController.formBlurred&#39;</span><span class="p">,</span>
<span class="nx">change</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">evt</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;formBlurred&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>You can then use this view as a sub view and capture the events. In the following example, a change to the Name input would blurr the form and cause the save button to appear.</p>
<div class="highlight"><pre><span class="nt">&lt;script </span><span class="na">id=</span><span class="s">&quot;formDetail&quot;</span> <span class="na">data-template-name=</span><span class="s">&#39;formDetail&#39;</span> <span class="na">type=</span><span class="s">&quot;text/x-handlebars&quot;</span><span class="nt">&gt;</span>
<span class="o">&lt;</span><span class="nx">form</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="nx">fieldset</span><span class="o">&gt;</span>
<span class="o">&lt;</span><span class="nx">legend</span><span class="o">&gt;</span><span class="nx">Info</span><span class="o">:&lt;</span><span class="err">/legend&gt; </span>
<span class="p">{{</span><span class="nx">view</span> <span class="nx">App</span><span class="p">.</span><span class="nx">myText</span> <span class="nx">name</span><span class="o">=</span><span class="s2">&quot;Name&quot;</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;Name&quot;</span> <span class="nx">valueBinding</span><span class="o">=</span><span class="s2">&quot;myObj.Name&quot;</span><span class="p">}}</span>
<span class="o">&lt;</span><span class="nx">label</span> <span class="k">for</span><span class="o">=</span><span class="s2">&quot;Name&quot;</span><span class="o">&gt;</span><span class="nx">Name</span><span class="o">&lt;</span><span class="sr">/label&gt;&lt;br/</span><span class="o">&gt;</span>
<span class="p">{{</span><span class="err">#</span><span class="k">if</span> <span class="nx">formBlurred</span><span class="p">}}</span>
<span class="o">&lt;</span><span class="nx">a</span> <span class="nx">href</span><span class="o">=</span><span class="s2">&quot;#&quot;</span> <span class="p">{{</span><span class="nx">action</span> <span class="s2">&quot;syncData&quot;</span> <span class="nx">on</span><span class="o">=</span><span class="s2">&quot;click&quot;</span><span class="p">}}</span><span class="o">&gt;</span><span class="nx">Save</span><span class="o">&lt;</span><span class="err">/a&gt;</span>
<span class="p">{{</span><span class="err">/if}}</span>
<span class="o">&lt;</span><span class="err">/fieldset&gt;</span>
<span class="o">&lt;</span><span class="err">/form&gt;</span>
<span class="nt">&lt;/script&gt;</span>
</pre>
</div>
</div>
<div class="section" id="views">
<h2 id='toc_views-in-depth'>Views In-Depth</h2>
<p>Now that you&#39;re familiar with using Handlebars, let&#39;s go more in-depth on
how to both handle events, and customize views to your needs.</p>
<h3 id='toc_handling-events'>Handling Events</h3>
<p>Instead of having to register event listeners on elements you&#39;d like to
respond to, simply implement the name of the event you want to respond to
as a method on your view.</p>
<p>For example, imagine we have a template like this:</p>
<div class="highlight"><pre>{{#view App.ClickableView}}
This is a clickable area!
{{/view}}
</pre>
</div>
<p>Let&#39;s implement App.ClickableView such that when it is
clicked, an alert is displayed:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">ClickableView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">click</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">evt</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;ClickableView was clicked!&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>Events bubble up from the target view to each parent view in
succession, until the root viewth of these values are read-only. If you want to manually manage views in JavaScript (instead of creating them
using the {{view}} helper in Handlebars), see the Ember.ContainerView documentation below.</p>
<h3 id='toc_manually-managed-views-with-ember-containerview'>Manually Managed Views with Ember.ContainerView</h3>
<p>Usually, views create their child views by using the <code>{{view}}</code> helper. Sometimes it is useful to manually manage a view&#39;s
child views. If you create an instance of <code>Ember.ContainerView</code>, the <code>childViews</code> array is editable. Views that you add
are rendered to the page, and views that you remove are removed from the DOM.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">container</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">ContainerView</span><span class="p">.</span><span class="nx">create</span><span class="p">();</span>
<span class="nx">container</span><span class="p">.</span><span class="nx">append</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">coolView</span> <span class="o">=</span> <span class="nx">App</span><span class="p">.</span><span class="nx">CoolView</span><span class="p">.</span><span class="nx">create</span><span class="p">(),</span>
<span class="nx">childViews</span> <span class="o">=</span> <span class="nx">container</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;childViews&#39;</span><span class="p">);</span>
<span class="nx">childViews</span><span class="p">.</span><span class="nx">pushObject</span><span class="p">(</span><span class="nx">coolView</span><span class="p">);</span>
</pre>
</div>
<p>As a shorthand, you can specify the child views as properties and the child views as a list of keys. When the
container view is created, these views will be instantiated and added to the child views array:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">container</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">ContainerView</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">childViews</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;firstView&#39;</span><span class="p">,</span> <span class="s1">&#39;secondView&#39;</span><span class="p">],</span>
<span class="nx">firstView</span><span class="o">:</span> <span class="nx">App</span><span class="p">.</span><span class="nx">FirstView</span><span class="p">,</span>
<span class="nx">secondView</span><span class="o">:</span> <span class="nx">App</span><span class="p">.</span><span class="nx">SecondView</span>
<span class="p">});</span>
</pre>
</div>
<h3 id='toc_render-pipeline'>Render Pipeline</h3>
<p>Before your views are turned into DOM elements, they first exist as a string representation. As views render, they turn
each of their child views into strings and concatenate them together.</p>
<p>If you&#39;d like to use something other than Handlebars, you can override a view&#39;s <code>render</code> method to generate a custom
string of HTML.</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">CoolView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span>
<span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">buffer</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;&lt;b&gt;This view is so cool!&lt;/b&gt;&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
</pre>
</div>
<p>This makes it easy to support template engines other than Handlebars; though do note that if you override rendering,
values will not update automatically. Any updates will be your responsibility.</p>
<h3 id='toc_customizing-the-html-element'>Customizing the HTML Element</h3>
<p>A view is represented by a single DOM element on the page. You can change what kind of element is created by
changing the <code>tagName</code> property.</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">tagName</span><span class="o">:</span> <span class="s1">&#39;span&#39;</span>
<span class="p">});</span>
</pre>
</div>
<p>You can also specify which class names are applied to the view by setting its <code>classNames</code> property to an array of strings:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">classNames</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;my-view&#39;</span><span class="p">]</span>
<span class="p">});</span>
</pre>
</div>
<p>If you want class names to be determined by the state of properties on the view, you can use class name bindings. If you bind to
a Boolean property, the class name will be added or removed depending on the value:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">classNameBindings</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;isUrgent&#39;</span><span class="p">],</span>
<span class="nx">isUrgent</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre>
</div>
<p>This would render a view like this:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;ember-view is-urgent&quot;</span><span class="nt">&gt;</span>
</pre>
</div>
<p>If isUrgent is changed to false, then the <code>is-urgent</code> class name will be removed.</p>
<p>By default, the name of the Boolean property is dasherized. You can customize the class name
applied by delimiting it with a colon:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">classNameBindings</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;isUrgent:urgent&#39;</span><span class="p">],</span>
<span class="nx">isUrgent</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">});</span>
</pre>
</div>
<p>This would render this HTML:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;ember-view urgent&quot;</span><span class="nt">&gt;</span>
</pre>
</div>
<p>If the bound value is a string, that value will be added as a class name without
modification.</p>
<h3 id='toc_attribute-bindings-on-a-view'>Attribute Bindings on a View</h3>
<p>You can bind attributes to the DOM element that represents a view by using <code>attributeBindings</code>:</p>
<div class="highlight"><pre><span class="nx">App</span><span class="p">.</span><span class="nx">MyView</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nx">View</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">tagName</span><span class="o">:</span> <span class="s1">&#39;a&#39;</span><span class="p">,</span>
<span class="nx">attributeBindings</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;href&#39;</span><span class="p">],</span>
<span class="nx">href</span><span class="o">:</span> <span class="s2">&quot;http://emberjs.com&quot;</span>
<span class="p">});</span>
</pre>
</div>
</div>
<div class="section" id="enumerables">
<h2 id='toc_the-ember-enumerable-api'>The Ember Enumerable API</h2><h3 id='toc_what-are-enumerables'>What Are Enumerables?</h3>
<p>In Ember, an Enumerable is any object that contains a number of child objects, and which allows you to work with those children using the Enumerable interface. The most basic Enumerable is the built-in JavaScript Array.</p>
<p>For instance, all Enumerables support the standard <code>forEach</code> method:</p>
<div class="highlight"><pre><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">].</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">item</span><span class="p">);</span>
<span class="p">});</span>
</pre>
</div>
<p>In general, Enumerable methods, like <code>forEach</code>, take an optional second parameter, which will become the value of <code>this</code> in the callback function:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">array</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">];</span>
<span class="nx">array</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">item</span><span class="p">));</span>
<span class="p">},</span> <span class="nx">array</span><span class="p">)</span>
</pre>
</div>
<p>Among other reasons, you will find this useful when using another Enumerable method as a callback to <code>forEach</code>:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">array</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">];</span>
<span class="nx">array</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">array</span><span class="p">.</span><span class="nx">removeObject</span><span class="p">,</span> <span class="nx">array</span><span class="p">);</span>
</pre>
</div>
<p>NOTE: This second parameter helps work around a limitation of JavaScript which sets the value of <code>this</code> to <code>window</code> in methods used this way.</p>
<h3 id='toc_enumerables-in-ember'>Enumerables in Ember</h3>
<p>In general, Ember objects that represent lists implement the Enumerable interface. Some examples:</p>
<ul>
<li><em>Array</em>: Ember extends the native JavaScript Array with the Enumerable interface.</li>
<li><em>ArrayProxy</em>: A construct that wraps a native Array and adds additional functionality for the view layer.</li>
<li><em>Set</em>: An object that can quickly answer whether it includes an object.</li>
</ul>
<h3 id='toc_the-enumerable-interface'>The Enumerable Interface</h3><h4 id='toc_parameters'>Parameters</h4>
<p>The callbacks to Enumerable methods take three arguments:</p>
<ul>
<li><em>item</em>: the item for the current iteration.</li>
<li><em>index</em>: an Integer, counting up from 0.</li>
<li><em>self</em>: the Enumerable itself.</li>
</ul>
<h4 id='toc_enumeration'>Enumeration</h4>
<p>To enumerate all the values of an enumerable object, use the <code>forEach</code> method:</p>
<div class="highlight"><pre><span class="nx">enumerable</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">self</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">item</span><span class="p">);</span>
<span class="p">});</span>
</pre>
</div>
<p>To invoke some method on each element of an enumerable object, use the <code>invoke</code> method:</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">sayHello</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Hello from &quot;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">people</span> <span class="o">=</span> <span class="p">[</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Juan&quot;</span> <span class="p">}),</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Charles&quot;</span> <span class="p">}),</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;Majd&quot;</span> <span class="p">})</span>
<span class="p">]</span>
<span class="nx">people</span><span class="p">.</span><span class="nx">invoke</span><span class="p">(</span><span class="s1">&#39;sayHello&#39;</span><span class="p">);</span>
<span class="c1">// Hello from Juan</span>
<span class="c1">// Hello from Charles</span>
<span class="c1">// Hello from Majd</span>
</pre>
</div>
<h4 id='toc_first-and-last'>First and Last</h4>
<p>You can get the first or last object from an Enumerable by getting <code>firstObject</code> or <code>lastObject</code>.</p>
<div class="highlight"><pre><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">].</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;firstObject&#39;</span><span class="p">)</span> <span class="c1">// 1</span>
<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">].</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;lastObject&#39;</span><span class="p">)</span> <span class="c1">// 3</span>
</pre>
</div>
<h4 id='toc_converting-to-array'>Converting to Array</h4>
<p>This one is simple. To convert an Enumerable into an Array, simply call its <code>toArray</code> method.</p>
<h4 id='toc_transforming'>Transforming</h4>
<p>You can transform an Enumerable into a derived Array by using the <code>map</code> method:</p>
<div class="highlight"><pre><span class="p">[</span><span class="s1">&#39;Goodbye&#39;</span><span class="p">,</span> <span class="s1">&#39;cruel&#39;</span><span class="p">,</span> <span class="s1">&#39;world&#39;</span><span class="p">].</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">item</span> <span class="o">+</span> <span class="s2">&quot;!&quot;</span><span class="p">;</span>
<span class="p">});</span>
<span class="c1">// returns [&quot;Goodbye!&quot;, &quot;cruel!&quot;, &quot;world!&quot;]</span>
</pre>
</div>
<h4 id='toc_setting-and-getting-on-each-object'>Setting and Getting on Each Object</h4>
<p>A very common use of <code>forEach</code> and <code>map</code> is to get (or set) a property on each element. You can use the <code>getEach</code> and <code>setEach</code> methods to accomplish these goals.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(),</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">()];</span>
<span class="c1">// we now have an Array containing two Ember.Objects</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">setEach</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">,</span> <span class="s1">&#39;unknown&#39;</span><span class="p">);</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">getEach</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span> <span class="c1">// [&#39;unknown&#39;, &#39;unknown&#39;]</span>
</pre>
</div>
<h4 id='toc_filtering'>Filtering</h4>
<p>Another common task to perform on an Enumerable is to take the Enumerable as input, and return an Array after filtering it based on some criteria.</p>
<p>For arbitrary filtering, use the (you guessed it) <code>filter</code> method. The filter method expects the callback to return <code>true</code> if Ember should include it in the final Array, and <code>false</code> or <code>undefined</code> if Ember should not.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">];</span>
<span class="nx">arr</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">item</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="p">}</span>
<span class="p">})</span>
<span class="c1">// returns [1,2,3]</span>
</pre>
</div>
<p>When working with a collection of Ember objects, you will often want to filter a set of objects based upon the value of some property. The <code>filterProperty</code> method provides a shortcut.</p>
<div class="highlight"><pre><span class="nx">Todo</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">title</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">isDone</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">});</span>
<span class="nx">todos</span> <span class="o">=</span> <span class="p">[</span>
<span class="nx">Todo</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Write code&#39;</span><span class="p">,</span> <span class="nx">isDone</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}),</span>
<span class="nx">Todo</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">title</span><span class="o">:</span> <span class="s1">&#39;Go to sleep&#39;</span> <span class="p">})</span>
<span class="p">];</span>
<span class="nx">todos</span><span class="p">.</span><span class="nx">filterProperty</span><span class="p">(</span><span class="s1">&#39;isDone&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="c1">// returns an Array containing just the first item</span>
</pre>
</div>
<p>If you want to return just the first matched value, rather than an Array containing all of the matched values, you can use <code>find</code> and <code>findProperty</code>, which work just like <code>filter</code> and <code>filterProperty</code>, but return only one item.</p>
<h4 id='toc_aggregate-information-all-or-any'>Aggregate Information (All or Any)</h4>
<p>If you want to find out whether every item in an Enumerable matches some condition, you can use the <code>every</code> method:</p>
<div class="highlight"><pre><span class="nx">Person</span> <span class="o">=</span> <span class="nx">Ember</span><span class="p">.</span><span class="nb">Object</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span>
<span class="nx">isHappy</span><span class="o">:</span> <span class="kc">false</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">people</span> <span class="o">=</span> <span class="p">[</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Yehuda&#39;</span><span class="p">,</span> <span class="nx">isHappy</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}),</span>
<span class="nx">Person</span><span class="p">.</span><span class="nx">create</span><span class="p">({</span> <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;Majd&#39;</span><span class="p">,</span> <span class="nx">isHappy</span><span class="o">:</span> <span class="kc">false</span> <span class="p">})</span>
<span class="p">];</span>
<span class="nx">people</span><span class="p">.</span><span class="nx">every</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;isHappy&#39;</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="p">}</span>
<span class="p">});</span>
<span class="c1">// returns false</span>
</pre>
</div>
<p>If you want to find out whether at least one item in an Enumerable matches some conditions, you can use the <code>some</code> method:</p>
<div class="highlight"><pre><span class="nx">people</span><span class="p">.</span><span class="nx">some</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">person</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">self</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">person</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;isHappy&#39;</span><span class="p">))</span> <span class="p">{</span> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> <span class="p">}</span>
<span class="p">});</span>
<span class="c1">// returns true</span>
</pre>
</div>
<p>Just like the filtering methods, the <code>every</code> and <code>some</code> methods have analogous <code>everyProperty</code> and <code>someProperty</code> methods.</p>
<div class="highlight"><pre><span class="nx">people</span><span class="p">.</span><span class="nx">everyProperty</span><span class="p">(</span><span class="s1">&#39;isHappy&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span> <span class="c1">// false</span>
<span class="nx">people</span><span class="p">.</span><span class="nx">someProperty</span><span class="p">(</span><span class="s1">&#39;isHappy&#39;</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span> <span class="c1">// true</span>
</pre>
</div>
</div>
</div>
</div>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.