Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a child route (or resource) access a parent resource's model from within the model hook?

Seems like in the case of nested routes, each route's model hook is called before any of the setupController hooks are called. So how can a child route safely access the parent's model?

In my case, the models aren't actually persisting entities. They're both generated, based on the params, in the model hooks. So I wouldn't think a Parent.find() / ajax / promise seems like the way to go. Ideally, the parent model should be accessible through the ParentController, no? Or is this approach not in keeping with best practices?

App.Router.map(function() {
  this.resource("parent", { path: "parent/:name" }, function() {
    this.route('child');
  });
});

App.ParentRoute = Ember.Route.extend({
  model: function(params) {
    // build a model here, based on params.
    // no asynch stuff happening, should be good to go.
    return { lastName: params.name }
  },

  setupController(controller, model) {
    controller.set('model', model);
  }
});

App.ChildRoute = Ember.Route.extend({
  model: function(params) {
    parentModel = this.controllerFor('parent').get('model');
    return {lastName: parentModel.get('name') + 'son' };

    // parent Model is null
    // need the parent model HERE, 
    // but I can't get it through the controller yet
    // as setupController in the parent route hasn't been called yet
  }
});
like image 353
doublea Avatar asked Sep 07 '13 02:09

doublea


2 Answers

doublea's answer still applies for Ember 3.x, with some slight changes to the boilerplate syntax of the route. Also the get is no longer necessary, but doesn't hurt anything to leave it there. Here's the 3.x syntax:

import Route from '@ember/routing/route';

export default Route.extend({
    model(params) {
       parentModel = this.modelFor('parent');
       return {lastName: parentModel.name + 'son' };
    }
});

For Ember 2.16 through at least all of Ember 3, another way to get information about parent routes is using the RouterService

Methods like currentRouteName and currentUrl can be helpful for display, although it's best to avoid fancy string parsing when there are better options. You can also use the router service's transitionTo in order to change routes from a Component.

The Router Service can be used like this:

import {inject as service} from '@ember/service';

export default Component.extend({
    router: service(),
    actions: {
      clickedAThing() {
        this.router.transitionTo('some.route')
      }
    }
})
like image 167
handlebears Avatar answered Oct 11 '22 22:10

handlebears


modelFor

How'd I miss that?

App.ChildRoute = Ember.Route.extend({
  model: function(params) {
    parentModel = this.modelFor('parent');
    return {lastName: parentModel.get('name') + 'son' };
  }
});
like image 42
doublea Avatar answered Oct 11 '22 21:10

doublea