The first object we’ll be covering is the Ember Route object. This is different from the Router. The Router creates named url routes. A Route object is a specific type of Ember object that helps you setup and manage what happens when you visit that url route.
Let’s say we want to show a list of users. First we would add a line to the router:
App.Router.map -> @resource 'users'
App.Router.map(function() { this.resource('users'); })
Now when you visit /users
, Ember will look for a UsersRoute
object. Here’s how that could look:
App.UsersRoute = Ember.Route.extend model: -> @store.find 'user'
App.UsersRoute = Ember.Route.extend({ model: function() { this.store.find('user') } })
model
is a function hook that’s called upon entering a route. The result of the model function is then accessible by other objects.
The store
is an Ember data construct that you go through when dealing with persisted records. find
fetches records of the type you pass it. It returns a promise, which in this case will return a DS.RecordArray
object once you call then
on it. DS.RecordArray
is essentially an array of models.
Route objects are really all about using hooks to prepare data and perform any setup actions required for the controller.
model
is just one of a series of hooks that are called when you enter a route. Here are a few more that you’ll get to know, listed in order of when they are called.
App.UsersRoute = Ember.Route.extend beforeModel: (transition) -> model: (params, transition) -> afterModel: (model, transition) -> activate: -> setupController: (controller, model) -> controller.set 'model', model #or @_super(arguments...) deactivate: ->
App.UsersRoute = Ember.Route.extend({ beforeModel: function(transition) { }, model: function(params, transition) { }, afterModel: function(model, transition) { }, activate: function() { }, setupController: function(controller, model) { controller.set('model', model) // or this._super(arguments...) }, deactivate: function() { } })
beforeModel
is called immediately before model
is called.
model
we just went over.
afterModel
is called after the model is resolved (i.e. either pulled down from the server or pulled out of the store).
activate
is called after all of the model hooks have completed, meaning that the route is now active.
setupController
is where you would do any controller setup. You get access to the controller itself as an argument. Note that if you implement setupController
you will need to set the model
property of the controller to the model
argument, because this hook overrides the parent. If you don’t do this then the controller will not have its model
property set. You could also call @_super(arguments...)
to accomplish the same thing.
deactivate
is called when you exit the route. It will not get called if you just change the model but stay on the same route. For example deactivate
would not get called if you changed from /users/1
to /users/2
The transition
argument being passed into the route model hooks can be used to abort the transition. For example, say we have a HouseRoute and you don’t like red houses:
App.HouseRoute = Ember.Route.extend afterModel: (model, transition) -> transition.abort() if model.get('color') is 'red'
App.HouseRoute = Ember.Route.extend({ afterModel: function(model, transition) { if (model.get('color') == 'red') { transition.abort() } } })
Here I’m using afterModel
, because the model is resolved and I can ask for its color property. If you abort, Ember will just go back to whatever route you came from. This can be handy for error checking, confirmation dialogs, and locking certain parts of your app depending on state.
Routes are the one place where you can reach across your app. Usually you do this to give the controller the information it needs.
this.modelFor('routeName')
will return the current model for that route.
this.controllerFor('controllerName')
will get that controller object. Sometimes you may want to get the model for that controller, in which case you would do this.controllerFor('controllerName').get('model')
.
Route objects are your friend. You’ll find that all of their hooks are extremely handy when you start trying to do fancy things in your app.