Rendering with Helpers Edit Page


Ember.js provides several helpers that allow you to render other views and templates in different ways.

The {{partial}} Helper

{{partial}} takes the template to be rendered as an argument, and renders that template in place.

{{partial}} does not change context or scope. It simply drops the given template into place with the current scope.

1
2
3
4
5
6
7
8
9
<script type="text/x-handlebars" data-template-name='_author'>
  Written by {{author.firstName}} {{author.lastName}}
</script>

<script type="text/x-handlebars" data-template-name='post'>
  <h1>{{title}}</h1>
  <div>{{body}}</div>
  {{partial "author"}}
</script>
1
2
3
4
5
<div>
  <h1>Why You Should Use Ember.JS</h1>
  <div>Because it's awesome!</div>
  Written by Yehuda Katz
</div>

The partial's data-template-name must start with an underscore (e.g. data-template-name='_author' or data-template-name='foo/_bar')

The {{view}} Helper

This helper works like the partial helper, except instead of providing a template to be rendered within the current template, you provide a view class. The view controls what template is rendered.

1
2
3
4
5
6
7
8
9
10
App.AuthorView = Ember.View.extend({
  // We are setting templateName manually here to the default value
  templateName: "author",

  // A fullName property should probably go on App.Author,
  // but we're doing it here for the example
  fullName: (function() {
    return this.get("author").get("firstName") + " " + this.get("author").get("lastName");
  }).property("firstName","lastName")
})
1
2
3
4
5
6
7
8
9
<script type="text/x-handlebars" data-template-name='author'>
  Written by {{view.fullName}}
</script>

<script type="text/x-handlebars" data-template-name='post'>
  <h1>{{title}}</h1>
  <div>{{body}}</div>
  {{view "author"}}
</script>
1
2
3
4
5
<div>
  <h1>Why You Should Use Ember.JS</h1>
  <div>Because it's awesome!</div>
  Written by Yehuda Katz
</div>

When using {{partial "author"}}:

  • No instance of App.AuthorView will be created
  • The given template will be rendered

When using {{view "author"}}:

  • An instance of App.AuthorView will be created
  • It will be rendered here, using the template associated with that view (the default template being "author")

For more information, see Inserting Views in Templates

The {{render}} Helper

{{render}} takes two parameters:

  • The first parameter describes the context to be setup
  • The optional second parameter is a model, which will be passed to the controller if provided

{{render}} does several things:

  • When no model is provided it gets the singleton instance of the corresponding controller
  • When a model is provided it gets a unique instance of the corresponding controller
  • Renders the named template using this controller
  • Sets the model of the corresponding controller

Modifying the post / author example slightly:

1
2
3
4
5
6
7
8
9
10
<script type="text/x-handlebars" data-template-name='author'>
  Written by {{firstName}} {{lastName}}.
  Total Posts: {{postCount}}
</script>

<script type="text/x-handlebars" data-template-name='post'>
  <h1>{{title}}</h1>
  <div>{{body}}</div>
  {{render "author" author}}
</script>
1
2
3
4
5
App.AuthorController = Ember.ObjectController.extend({
  postCount: function() {
    return this.get("model.posts.length");
  }.property("model.posts.[]")
})

In this example, render will:

  • Get an instance of App.AuthorView if that class exists, otherwise uses a default generated view
  • Use the corresponding template (in this case the default of "author")
  • Get (or generate) the singleton instance of AuthorController
  • Set the AuthorController's model to the 2nd argument passed to render, here the author field on the post
  • Render the template in place, with the context created in the previous steps.

{{render}} does not require the presence of a matching route.

{{render}} is similar to {{outlet}}. Both tell Ember.js to devote this portion of the page to something.

{{outlet}}: The router determines the route and sets up the appropriate controllers/views/models. {{render}}: You specify (directly and indirectly) the appropriate controllers/views/models.

Note: {{render}} cannot be called multiple times for the same route when not specifying a model.

Comparison Table

General

Helper Template Model View Controller
{{partial}} Specified Template Current Model Current View Current Controller
{{view}} View's Template Current Model Specified View Current Controller
{{render}} View's Template Specified Model Specified View Specified Controller

Specific

Helper Template Model View Controller
{{partial "author"}} author.hbs Post App.PostView App.PostController
{{view "author"}} author.hbs Post App.AuthorView App.PostController
{{render "author" author}} author.hbs Author App.AuthorView App.AuthorController