29

I've been reading a lot on emberjs lately but something isn't really clear to me: I have a feeling that there are different ways of rendering a template. Can someone explain the differences between these:

{{render}}
{{partial}}
{{template}}
{{outlet}}

I'm using pre4, so if some of these keywords are obsolete, please notify.

polyclick
  • 2,704
  • 4
  • 32
  • 58

3 Answers3

56

You can search the Ember.JS source for all of these by searching for: Ember.Handlebars.registerHelper('?'. For example, to find the part where template is defined, search for: Ember.Handlebars.registerHelper('template'

{{template}}

Is similar to the {{partial}}, but looks for templates that you define in the Ember.TEMPLATES hash. From the source code we can see an example: Ember.TEMPLATES["my_cool_template"] = Ember.Handlebars.compile('<b>{{user}}</b>'); and then we can render it that way.

I heard a whisper that {{template}} is @deprecated, but I can't find where I found that information at the moment. However, it's worth mentioning that I've never found myself using this one. Instead I prefer {{partial}}.

Edit: It appears as though it isn't @deprecated as of 3df5ddfd4f. My mistake!

{{partial}}

This is different to the {{render}} approach in that the controller and view are inherited from the context that called it. For example, if you're in the UserRoute, and you load in a partial in your user template, then the UserView and UserController will both be passed to your partial, so they can access exactly the same information as its current parent.

Partial names, when defined, start with an underscore. For instance, a Profile partial will have the data-template-name of: data-template-name="_profile" but is inserted into your view as {{partial "profile"}}.

{{outlet}}

You'll probably find yourself using this one a lot. It's predominantly used in cases where the outlet changes frequently, based on user interactions. By transitioning to (this.transitionTo/{{#linkTo}}) another page, Ember inserts the view into the {{outlet}} and attaches the relevant controller and view.

As an example, if you're transitioning into /#/pets then, by default, Ember will load the PetsView into the {{outlet}}, and attach the PetsController, all of this after initialising the PetsRoute to take instructions before initialising the view and finding the controller.

{{render}}

This is a mixture of an {{outlet}} and a {{partial}}. It's used for static pages that don't switch out for other pages (as an outlet does), but it doesn't inherit the controller and view (as a partial does).

It's better with an example. Let's say you've got a navigation. Usually you'll only have one navigation, and it won't change for another one, but you want the navigation to have its own controller and view, and not to be inherited from the context (probably ApplicationRoute). Therefore when you insert the navigation ({{render "navigation"}}), Ember will attach App.NavigationController and App.NavigationView.

Summary

  • template: Consults a global hash and inserts the view when it finds it (possibly soon to be @deprecated);
  • partial: Used to split up complicated views, and inherits the controller/view from the parent (if you're in the UserController, then the partial will also have access to this, and its associated view).
  • outlet: Most widely used, and allows you to quickly switch out pages for other pages. Relevant controller/view attached.
  • render: Similar to an outlet, but is used for pages that are persistent across the entire application. Assumes the relevant controller/view, and doesn't inherit them.

Did I explain them well?

Just to clarify:

  • Partial: Inherited controller, inherited view, non-switchable;
  • Outlet: Relevant controller, relevant view, switchable;
  • Render: Relevant controller, relevant view, non-switchable;
Wildhoney
  • 4,969
  • 33
  • 38
  • Awesome answer, vote up! This actually confirms what I was assuming the different keywords do. Would be great if someone can confirm the @deprecated. – polyclick Feb 10 '13 at 22:06
  • My pleasure! It's useful for me as well, especially as I've just compiled the very latest version of Ember after a `git pull`, and put together a JSFiddle to demonstrate everything: http://jsfiddle.net/HvXNh/ It appears as though `{{render}}` isn't **@deprecated** as I thought. The JSFiddle should help you understand the differences. – Wildhoney Feb 10 '13 at 22:24
  • 3
    Wow, that increased my ember knowledge by aprox. 30%. – James Andres Feb 11 '13 at 01:28
  • Great answer! What about `{{view}}`? I'm curious to know how it compares to, say, using a partial. – NudeCanalTroll Feb 13 '13 at 06:12
  • 4
    `{{view}}` is pretty basic, it'll just insert the `view` into your template, and inherit the `controller` from what inserted it. I've updated the fiddle: http://jsfiddle.net/HvXNh/1/ I use `{{view}}`s to insert relative views (those that reside in my current view), because specifying the absolute path of the view (`{{view App.MyView}}`) is far from ideal. Specifying its label and letting Ember find and insert it is a better approach: `{{template "myTemplate"}}`. – Wildhoney Feb 13 '13 at 09:44
  • great answer... and how does {{control}} fit into the equation? – Ben Apr 18 '13 at 07:08
  • Could you describe what you mean by inheritance? – Rose Perrone Apr 22 '13 at 15:10
  • @WildHoney Any chance you could update this answer to remove the currently deprecated features? Google drove me here. – PW Kad Mar 26 '14 at 18:30
  • @PWKad could you edit my answer accordingly please? I haven't had too much dealings with Ember.js as of late, I've taken the step over to the darkside with Angular.js. – Wildhoney Mar 27 '14 at 10:24
4

The guide also provides some useful information here! Below is a quick summary:

enter image description here

TrevTheDev
  • 2,616
  • 2
  • 18
  • 36
  • Note that [link-only answers are discouraged](http://meta.stackoverflow.com/tags/link-only-answers/info), SO answers should be the end-point of a search for a solution (vs. yet another stopover of references, which tend to get stale over time). Please consider adding a stand-alone synopsis here, keeping the link as a reference. – kleopatra Jan 13 '14 at 09:56
4

I wanted to post another answer here that really helped me to clarify when to use the various template techniques -

Route

Using a route is when you need a full-blown route. A 'route' has a unique URL and consists of generated or user defined classes of the following type -

  1. Route (Ember.Route)
  2. Controller (Ember.Controller || Ember.ArrayController || Ember.ObjectController)
  3. View (Ember.View)
  4. Template (Handlebars template)

{{render}}

Use the {{render}} helper when you need a view but still need to provide some functionality with a controller. {{render}} does not have a unique URL and consists of the following -

  1. Controller (Ember.Controller || Ember.ArrayController || Ember.ObjectController)
  2. View (Ember.View)
  3. Template (Handlebars template)

{{component}}

Use the {{component}} helper when you are building a commonly re-used template which exists independent of the context it is rendered within. An decent example may be if you were building a retail website and wanted to have a product view agnostic of where it is rendered. {{component}} does not have a unique URL nor a controller but instead has a component class and consists of the following -

  1. Component (Ember.Component)
  2. Template (Handlebars template)

{{partial}}

Use the {{partial}} helper when you are simply re-using some mark-up. {{partial}} does not have a unique URL nor any special backing like a component and consists of the following -

  1. Template (Handlebars template)
PW Kad
  • 14,953
  • 7
  • 49
  • 82
  • Can render be used only once? I am faced with errors like : 'You can only use the {{render}} helper once without a model object' – Ajoy Jun 19 '14 at 10:27