I'm attempting to learn Ember for the second time. My first attempt was over six months ago and so much has changed that it might as well be a different framework. It's not going too great so far. I'm finding myself spending more time on StackOverflow than writing code. I believe the questions I have now plague every Ember newbie. I know that I will think these questions are dumb once I have gained more experience with the framework, but I thought I'd list them here in hopes that someone wouldn't have to spend hours googling just to find out that they are doing something in a way that is deprecated or outdated in the latest version of Ember. I better hurry though. Ember.js is evolving so fast that if it takes me more than a few days to write this post everything in it will be outdated.

What is the difference between App.Router.map(function()... and App.Router.map(function(match)...?

I found router examples using both variants and it confused the hell out of me. It seemed like they were both being used in about the same time period so I did not think it was a change in the framework but instead an variation in the use of the router.

One example shows something like:

App.Router.map(function(match) {  match("/").to("home");});

As shown in this Tomdale gist.

App.Router.map(function() {  this.resource('posts');});

As found in the documentation.

I've found that the RC1 release changed the way the router works and the documentation has it right this time. Here is how I match specific routes:

App.Router.map(function() {  this.route('home', { path: "/" });});

What is the difference  between {{template}} {{partial}} {{outlet}} {{render}} {{control}} {{view}}?

I found these articles and they sum up the difference pretty well:

I'll summarize them here based on my understanding of their purpose and the use cases for each. First, here is a basic layout that uses many of them:

<div>
  {{ partial "menu" }}|
  {{ render "account" App.currentUser }}
</div>
<div>{{ outlet sidebar }}</div>
<div>{{ outlet }}</div>
<div>
  {{ control "ad" controlID="left-ad" }}
  {{ control "ad" controlID="right-ad" }}
</div>
<div>{{ view App.FooterView }}</div>

{{template}} and {{partial}}

These two are confusing because the Ember.js documentation does not mention {{partial}}, only {{template}}. However, most of the recent community tutorials use {{partial}} and say that {{template}} is soon to be deprecated.

As far as I can tell they have the same effect; they render a named template without hitting the router/controller/view (none of the helpers hit the router actually). They seem to be geared toward reusable pieces of html that don't need to interact with a controller. They are bound to the current context with no apparent way to pass in the model, so I have started wrapping {{partial}} calls with a {{#with}} block to define the context of the partial.

{{#with foo}}{{partial "foo"}}{{/with}}

In Rails using the Ember-Rails gem, this template will be loaded from _foo.handlebars. For an embedded template it will use the data-template-name attribute to find the template by name.

<script type="text/x-handlebars" data-template-name="_foo">...</script>

The only real difference between these helpers is that {{partial}} expects the name of the template to begin with an underscore, although it will work without it and give a warning.

{{outlet}}

At first I was confused about the point of an outlet and the difference between {{outlet}}, {{render}}, and the new {{control}} helper. The name to me invokes the iOS style outlet that provides a channel for the controller to manipulate the view. It would make since then that the context of the named outlets is set by the controller that invoked this template. My current thought is that outlets define content specific sections of the page like content (obviously), sidebar, details, and sub-menus.

Outlets allow the content from multiple controllers to be displayed. They are the heavy lifters in an Ember app. An outlet is declared in a template like this:

{{ outlet }}

The default outlet is view so this is the same as:

{{ outlet view }}

Specifying a name for an outlet provides an id for the controller to differentiate outlets.

{{ outlet sidebar }}

As far as I can tell there is no automatic mapping of named outlets to controller (only the default one). This is something you have to setup in the router:

App.HomeRoute = Ember.Route.extend({
  renderTemplate: function() {        
    this.render('sidebar', {      
      view: 'sidebar',
      outlet: 'sidebar',
      into: 'application', // the template name?        
      controller: this.controllerFor('sidebar')      
    });  
  },
  ...
});

This seems simple so just to confuse us there is also another way to do this using connectOutlets:

App.HomeRoute = Ember.Route.extend({
  connectOutlets: function(router, event) {            
    router.get('sidebarController').connectOutlet('sidebar');  
  },
  ...
});

I'm not sure if one of these methods is deprecated but I see current examples using both so I guess it's a style issue. I prefer the connectOutlets method because it tells you exactly whats going on. You are connecting outlets.

It would seem that outlets should not require a model to be passed in but would instead hit the router to get data and be directed to a controller to determine what view to render. They actually don't hit the router however. It looks like the loaded route is responsible for setting up all named outlets. Ember.Route has a method called setupController that is used to load the model for the main controller as well as for the various named outlet controllers.

App.HomeRoute = Ember.Route.extend({
  setupController: function(controller) {    
    this.controllerFor('sidebar').set('content', Ember.A([...]));  
  },
  ...
});

This seems like it could cause you to duplicate code in each routes setupController. I've seen a few examples of creating generic routes and inheriting from them. So far I have not run into this problem. It seems to me that all this wire-up code could be removed if outlets could hit a route directly. Then I would just create an App.SidebarRoute. That way only the sidebar is ever concerned with it's model.

So my conclusion is that outlets are areas that render their own data and handle their own interaction but are for some reason dependent on the main content. Think of a sidebar that shows information related to the current product being viewed or actions that can be taken on the current post.

{{render}}

Render is just like outlet in that it creates the appropriate controller and view based on the name provided. The only difference is that the model is passed as the third parameter.

{{ render "accountBar" App.currentUser }}

This would create an accountBarController and set the content to App.currentUser. This never needs to be touched again for any route. The account bar will always show the current user.

There is one major problem with {{render}}. It can only be used once. This is very counter-intuitive because most MVC web frameworks have the concept of render and they have no problem being called multiple times. Rather than fix the problem there seems to be an experimental fix in the works called {{control}}... up next.

{{control}}

This is just like render but it can be called multiple times. I've tested this and found that while it does not throw an error like render does, it reuses the controller created in the first call. This means that if you call it in a loop like this:

{{#each post in posts}}
  <li>{{control "post" post}}</li>
{{/each}}

only one postController is created. Since passing the post variable sets the content of the postController, the last item in the list will be rendered in every <li>. This bug is being worked on. Supposedly you can pass in a controlID to differentiate them and a new controller will be created for each.

<li>{{control "post" post controlID="uniqueKey"}}</li>

I have not been able to get that to work because you can't easily use a distinct field on the model as the controlID. There is also a way to set a controller as a non-singleton, meaning that a new one will always be created when its resolved.

App.register('controller:post', App.PostController, {
  singleton: false
});

I haven't tried this yet so I can't comment on whether this solves the issue.

Just as a last note, it seems that the {{control}} helper may be replaced by the new itemController in RC1. Since the individual itemController is already created within the #each block you can use a simple {{view}} call to render the template. This is covered next.

{{view}}

{{view}} is between {{render}} and {{template}}. It creates a specific view by class name and that view is responsible for defining the corresponding template. It doesn't create a controller. This lead me to believe that {{render}} should actually be called {{controller}} but that's off topic. Here is the basic use of {{view}}:

{{view App.PostView}}

Many properties can be set here directly. Binding the content would be done like this:

{{view App.PostView contentBinding="post"}}

Here is an example of how the {{view}} helper along with the itemController property helps to eliminate the need for the {{control}} helper:

{{#each post in posts itemController="post"}}
  <li>{{view App.PostView contentBinding="post"}}</li>
{{/each}}

I was able to get this working and it is currently my preference over using {{control}} in an #each loop. I did have to manually set the view's template name even though it seemed to follow the naming convention:

App.PostView = Ember.View.extend({templateName:"post"});

I wasn't sure if this was actually hooking up the controller to the view but if I remove just the itemController="post" property it causes the databinding to break. So I guess this is correct.

Who is Metamorph, and what does he do?

Coming Soon!

How do I use Ember without Ember-data?

It's not that I don't want to use Ember-data, but I want to know where Ember stops and Data begins. None of the tutorials, documentation, or examples I have found use vanilla Ember.Objects as their models. Here is what I have found so far:

Coming Soon!