Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 48 additions & 44 deletions guides/v3.1.0/controllers/index.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
## Controllers
### What is a Controller?

Controllers behave like a specialized type of Component that is rendered by
the router when entering a Route.
A [Controller](https://emberjs.com/api/ember/release/classes/Controller) is routable object which receives a single property from the Route – `model` – which is the return value of the Route's [`model()`](https://emberjs.com/api/ember/3.1/classes/Route/methods?anchor=model) method.

The controller receives a single property from the Route – `model` – which is
the return value of the Route's `model()` method.
The model is passed from the Route to the Controller by default using the [`setupController()`](https://www.emberjs.com/api/ember/3.1/classes/Route/methods/setupController?anchor=setupController) function. The Controller is then often used to decorate the model with display properties such as retrieving the full name from a name model.

To define a Controller, run:
A Controller is usually paired with an individual Route of the same name.

### Defining a Controller

We only need to generate a Controller file if we want to customize the properties or provide any actions to the Route. If we have no customizations, Ember will provide a default Controller instance for us at run time.

To generate a controller, run
```bash
ember generate controller my-controller-name
```

The value of `my-controller-name` must match the name of the Route that renders
it. So a Route named `blog-post` would have a matching Controller named
`blog-post`.
This creates a controller file at `app/controllers/my-controller-name.js`, and a unit test file at `tests/unit/controllers/my-controller-name-test.js`.

The controller name `my-controller-name` must match the name of the Route that renders it. So if the Route is named `blog-post`, it should have a matching Controller named `blog-post`. The matching file names of the Controller and the Route signals to Ember that this Controller must be used when landing on the `blog-post` Route.

### Where and When to use Controllers?

Controllers are used as an extension of the model loaded from the Route. Any attributes or actions that we want to share with components used on that Route could be defined on the Controller and passed down through the Route’s template.

You only need to generate a Controller if you want to customize its
properties or provide any `actions`. If you have no customizations, Ember will
provide a Controller instance for you at run time.
Controllers are singletons so we should avoid keeping state that does not derive from either the Model or Query Parameters since these would persist in between activations such as when a user leaves the Route and then re-enters it.

Let's explore these concepts using an example of a route displaying a blog
post. Presume a `BlogPost` model that is presented in a `blog-post` template.
Controllers can also contain actions that enable the Route's components to update the Model or Query Parameters through it using Computed Properties.

### Basic Controller Example

Let's explore these concepts using an example of a route displaying a blog post. Assume that the route returns a `BlogPost` model that is presented in the template.

The `BlogPost` model would have properties like:

Expand All @@ -30,8 +38,7 @@ The `BlogPost` model would have properties like:
* `body`
* `author`

Your template would bind to these properties in the `blog-post`
template:
In the example below, we can see how the template is using the model properties to display some data.

```handlebars {data-filename=app/templates/blog-post.hbs}
<h1>{{model.title}}</h1>
Expand All @@ -46,15 +53,23 @@ template:
</div>
```

In this simple example, we don't have any display-specific properties
or actions just yet. For now, our controller's `model` property acts as a
pass-through (or "proxy") for the model properties. (Remember that
a controller gets the model it represents from its route handler.)
Consider the example where we want to have a controller for a `blog-post` route. In this controller, we are looking to keep track if the user has expanded the body or not.

```javascript {data-filename=app/controllers/blog-post.js}
import Controller from '@ember/controller';

export default Controller.extend({
isExpanded: false,

actions: {
toggleBody() {
this.toggleProperty('isExpanded');
}
}
});
```

Let's say we wanted to add a feature that would allow the user to
toggle the display of the body section. To implement this, we would
first modify our template to show the body only if the value of a
new `isExpanded` property is true.
The property `isExpanded` keeps track if the user has expanded the body or not. The action `toggleBody()` provides a way for the user to provide their setting. Both of the them are used in the updated template below.

```handlebars {data-filename=app/templates/blog-post.hbs}
<h1>{{model.title}}</h1>
Expand All @@ -75,27 +90,16 @@ new `isExpanded` property is true.
{{/if}}
```

You can then define what the action does within the `actions` hook
of the controller, as you would with a component:

```javascript {data-filename=app/controllers/blog-post.js}
import Controller from '@ember/controller';

export default Controller.extend({
isExpanded: false,

actions: {
toggleBody() {
this.toggleProperty('isExpanded');
}
}
});
```
We can see that if the property `isExpanded` is toggled to true, we will show the body property of the model to the user. This `isExpanded` is stored in the controller.

### Common questions

<div class="common-question">
<h4>Should I use controllers in my application? I've heard they're going away!</h4>
###### Should we use controllers in my application? I've heard they're going away!

<p>Yes! Controllers are still an integral part of an Ember application architecture, and generated by the framework even if you don't declare a Controller module explicitly.</p>
</div>
Yes! Controllers are still an integral part of an Ember application architecture, and generated by the framework even if you don't declare a Controller module explicitly.

###### When should we create a Controller?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the content of this section be rolled into "When and where to use controllers"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on leaving this here? I think it might be quoted a bit and wanted it in the same place for people to see

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with either


* We want to pass down actions or variables to share with a Route’s child components
* We have a computed property that depends on the results of the model hook
* We need to support query parameters