May 04, 2015
Table of contents:
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.
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.
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({});
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
}.property("model.wordCount"),
});
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
{{/each}}
{{else}}
<button {{action 'showComments'}}>Show Comments</button>
{{/if}}
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.