Router flow from link-to
In this guide we will explore the steps Ember performs when a user
clicks on a link generated by the link-to
helper. Ember has a number
of useful hooks you can overwrite to run code during the various
phases of the transition.
Lets imagine a user is on the /about/faq/
page of an application
with the following router.
App.Router.map(function() {
this.resource('about', function() {
this.route('faq');
});
this.resource('user', { path: '/user/:user_id' }, function() {
this.route('profile');
});
});
This would mean there are currently three nested active routes in this
application. The ApplicationRoute
, AboutRoute
and the AboutFaqRoute
.
Lets assume a user clicks on a link-to
for the UserProfileRoute
like
the one below.
Visit your user profile
Ember will perform a number of steps before transition a user to the user profile page. Broadly these steps are grouped into three phases, the Pre Transition Phase, the Model Resolution Phase and the Sync Phase. We will explore these phases in more depth below.
Pre Transition Phase
First Ember will create a transition object. This object is a promise
which will be resolved when the transition is complete or rejected
when the random is aborted. The transition object can be used to abort
the transition by calling transition.abort()
.
Next Ember will trigger a willTransition
action on the currently
active routes starting with the leaf-most route (in this example the
AboutFaqRoute
).
The argument for the willTransition
action is the transition
object. This gives each active route, the opportunity to decide
whether or not the transition should occur. The code to intercept the
willTransition
action and abort a transition might looks something
like this.
App.AboutFaqRoute = Ember.Route.extend({
actions: {
willTransition: function(transition) {
if (this.controllerFor('form').get('userHasEnteredData') &&
!confirm("Are you sure you want to abandon progress?")) {
transition.abort();
} else {
// Bubble the `willTransition` action so that
// parent routes can decide whether or not to abort.
return true;
}
}
}
});
If the transition is not aborted then Ember will attempt to resolve the model.
Model Resolution / Validation Phase
The purpose of this phase is both to collect and resolve all model promises for newly entered routes (or routes with updated contexts), as well as allow for any of the beforeModel / model / afterModel hooks to reject elsewhere. If any of these hooks return a promise, the transition will pause until the promise resolves/rejects.
If the promise rejects, and error
action is triggered from the
erroring route and upwards with the rejected/thrown error. Calling
transitionTo
elsewhere will abort the transition as well (but fire
no errors).
Sync exit/enter/setup Phase
After the transition has been validated and any models are resolved ember enters the Sync exit/enter/setup Phase. Here Ember calls exit on the existing routes and enter / setup on the newly entered routes.
If any errors are thrown, the transition promise will be rejected and
the error
action will be triggered from the erroring route and
upwards with the rejected/thrown error.
If no errors are thrown then the internal transition promise is resolved and the user is now on the profile page.