Using Controllers in Ember

May 04, 2015

Table of contents:

  1. The Controller’s role
  2. Creating a new Controller
  3. Setting Controller properties
  4. Dealing with actions
  5. Conclusion

Last week we looked at Ember Routes. The Route is responsible for providing the model data, selecting the controller and rendering the template.

The Controller is an important and well recognised component of the MVC paradigm.

Controller’s in Ember sit between the Template and the Model to deal with logic and properties that do not belong to the View or the Model.

In today’s tutorial we’re going to be looking at the role of Controllers in Ember applications.

The Controller’s role

In last week’s post, we saw how it is the Route’s responsibility for providing the model to the View.

In last week’s post we provided the Route with a simple object of data. We then saw how this data was made available to the Template.

The Route does not pass the model properties directly to the View. Instead, the Route assigns the model property of the Controller. It is the Controller’s responsibility for providing the data to the Template.

It is also the Controller’s responsibility for dealing with properties and logic that do not belong to the View or the Model. The Controller knows about the Model, but the Model does not know about the Controller.

Creating a new Controller

Following on from the working example from the last couple of weeks, we can create a new Controller by using Ember CLI’s generate command:

ember g controller posts

This should create a posts.js file under the controllers directory in your project:

import Ember from "ember";

export default Ember.Controller.extend({});

Setting Controller properties

When you have a property that is important to the Template, it can be tempting to just shove it in the Model. However often properties that relate to display logic have no place in the persisted data store.

Instead we can provide these properties as part of the Controller:

export default Ember.Controller.extend({
  canEdit: true,

We can now access this property in the Template using the normal Handlebars helpers:

{{#if canEdit}} // Provide form to edit the post {{/if}}

We can also use the Controller to make model data more friendly to the user. For example, imagine we had the the number of words of an article stored as part of the model data.

Instead of displaying the number of words, we want to provide the user with a reading time estimate. We can provide this with a computer property:

export default Ember.Controller.extend({
  readingEstimate: function () {
    // Calculate the reading estimate

Dealing with actions

Another concern of the Controller is to deal with the logic around actions. An action is something that is triggered in the Template by the user.

For example, by default we might not want to show comments as part of the post:

export default Ember.Controller.extend({
  displayComments: false,

In the template we might have the following mark up to display the comments section:

{{#if displayComments}}
    <button {{action 'hideComments'}}>Hide Comments</button>
    {{#each comments in model.comments}}
        // display comments
    <button {{action 'showComments'}}>Show Comments</button>

To enable this functionality we can add the following actions to the controller:

export default Ember.Controller.extend({
  displayComments: false,

  actions: {
    showComments: function () {
      this.set("displayComments", true);

    hideComments: function () {
      this.set("displayComments", false);


In today’s tutorial we’ve only really touched upon Controllers in Ember. There is still a lot more to look at with using Controllers, but sometimes I think it’s better to get into the nitty gritty with real life usage, rather than simple examples.

It’s important to understand how Controllers work, what are the Controller’s responsibility and how they fit into the framework.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown


© Yellow Flag Ltd 2024.