Ember.Route.model
has access to the params
variable, but Ember.Route.setupController
does not. This is troublesome for me, because my path has multiple dynamic segments, and I need to use all of them in my template.
Specifically, my path looks like this: /project/:project_id/task/:task_id
. Note that a task can belong to many projects, not just one. Therefore we can't tell what project we're looking at just be looking at the task itself: we have to use the project ID found in the URL. Here's how I'm doing it currently:
App.TaskRoute = Ember.Route.extend({
// This works just fine:
serialize: function(model) {
return {
task_id: model.get('id'),
project_id: this.modelFor('project').get('id')
};
},
model: function(params) {
this.set('parentProjectId', params.project_id);
return App.Task.find(params.task_id);
},
setupController: function(controller, model) {
var parentProject = this.modelFor('project') ?
this.modelFor('project') :
App.Project.find(this.get('parentProjectId'));
controller.set('parentProject', parentProject);
controller.set('content', model);
}
});
Maybe I'm being paranoid, this just feels hacky. If the route was meant to have access to the parameters, then it would already have a params
property attached to it. Is there a better way?
EDIT: I made some update to the code above. Also, my routes look like this:
App.Router.map(function() {
this.resource('project', { path: '/project/:project_id' });
this.resource('task', { path: 'project/:project_id/task/:task_id' });
});
You have no access to these params in the setupController hook. The model hook has access to a params object, because it is just called, when your app is entered via URL.
Your code looks quite fine, it you really know, that you want to do it this way. What does feel hacky to you about it? When looking at this code, i am asking myself why you did not split the logic of your Route into a ProjectRoute and a subordinated TaskRoute. Wouldn't that work for you?
Update: Response to your changes
Nesting resources is likely the key to success in your case:
App.Router.map(function() {
this.resource('project', { path: '/project/:project_id' }, function(){
this.resource('task', { path: '/task/:task_id' });
});
});
Since the TaskRoute is nested not you have to rename it to ProjectTaskRoute:
App.ProjectTaskRoute = Ember.Route.extend({
...
});
This should enable you to remove the parentProjectId property
from the Route.
Since Ember 1.8, the Route class has a paramsFor function:
import Route from '@ember/routing/route';
export default Route.extend({
setupController(controller) {
this._super(...arguments);
const params = this.paramsFor('name.of.your.route')
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With