Router is the core part of Ember. Every time we go to a new URL it means the route object is called with our params and stuff. These are the hooks sorted in order in which they are called
- enter (private)
- activate - executed when entering the route
- deserialize (private)
- model (formely deserialize) - takes the params and returns a model
which is set to the route’s
currentModel
- serialize - used to generate dynamic segments in the URL from a model
- setupController - takes
currentModel
and sets it to the controller’scontent
by default - renderTemplate - takes current controller and what
model
returns and renders the template with an appropriate name - deactivate - executed when exiting the route (called by exit internally)
- exit (private, requires call to
this._super
)
Now let’s take a look at them in more detail
activate
/deactivate
These were formely known as enter
/exit
, which are now marked as
private. activate
will be executed when user enters a route, be it
from a transition or from a URL directly, and deactivate
is executed
when user transitions away from the route.
One of the most common use cases for me is doing a transaction rollback
in deactivate
.
1 2 3 4 5 6 7 |
|
I find this mostly useful when having a new record form (or even when editing a record), where you basically want to rollback any changes which happened when the user exits the route. It doesn’t matter if the user submits the form first, because then the transaction will be comitted and there will be nothing to rollback.
model
/serialize
To allow Ember to work with dynamic segments in the URLs we need to
teach it how to serialize and deserialize our models. When we enter a
URL directly (or reload the page) model
will be called with params
from the dynamic segments. Let’s take a look at an example
1 2 3 4 5 6 7 8 9 10 11 |
|
This is exactly what Ember will auto generate for us, along with a serialize hook
1 2 3 4 5 6 7 8 9 10 11 |
|
it is important to note here that if we’re transitioning from a
different route our model
hook will not be called.
setupController
One step further after model
comes setupController
, which is meant
to set additional properties on the controller, or override it’s
content
.
But beware, there is no autogenerated setupController
hook which sets to content
,
this is done even before setupController
is called in the setup
hook of the route. This is basically simulates the following:
1 2 3 |
|
But it also means we can set additional properties on the controller without needing to explicitly set the content
1 2 3 |
|
renderTemplate
The last one of the hooks is renderTemplate
where you tell which
template you want to render in which outlet.
By default renderTemplate
will call this.render
as follows
1 2 3 4 5 6 7 8 9 10 11 |
|
In this case render
will render the post
template into the
application
template’s main
outlet with the PostController
.
This is the place where you can chose to render into other outlets. For
example let’s say that your application
template has a sidebar outlet
“.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Important notes about controllerFor
and modelFor
While calling controllerFor("posts")
returns an instance of
PostsController
, calling modelFor("posts")
doesn’t return
content
of the PostController
. Instead it looks up the PostsRoute
and
returns it’s currentModel
which is set when we return a value from the
model
hook.
Let’s see an example
1 2 3 4 5 6 7 |
|
This will cause issues if we decide to use modelFor
later on.
PostsRoute
will not have anything in currentModel
and modelFor
will return undefined, which might look weird as the controller has a
content properly set.