Why is setupController called after the model hook of nested routes?


#1

Hello

I’ve found out, that the setupController hook of a route that contains nested routes is always called after the mode hook of the nested route. This confuses me, because so I can not access a ready Controller inside the childs model hook.

In my opinion its much more logical to call beforeModel, model, afterModel and setupController in a row, and then go on to the childs hooks.

Why is it done in the other way, what is the reason?

Thanks


#2

I’m not sure exactly why this particular order, but my guess is that its related to how nested routes are intended to be used. Nested Routes (in Ember) imply that nested route’s template is being displayed inside of parent route’s template.

Why are you trying to access the “ready Controller” inside the child’s model hook? What are you trying to accomplish?


#3

@tarasm: Because I wanna store ‘global’ like stuff on the application and a private Controller whats advised here by @wycats

So I set it on setupController and then I need it in the nested routes modelhook to give it to my backand.


#4

I think for what you’re trying to accomplish, you would be better off using injections. Here is a good explanation of how to use it http://stackoverflow.com/a/18210271/172894


#5

@tarasm: Very intresting, its just sad that theres not much documentation about injection. So can I only inject into controllers and routes, or any kind of object? If yes how?

At least, thank u very much. I will check this out.


#6

@krutius I started an article about injections for Ember Sherpa but there are some inconsistencies that caused me to put it on hold. The inconsistencies are described in this issue.

You can inject into any kind of object as long as the object, take a look at this JSBin http://jsbin.com/aguLeDi/7/edit


#7

@tarasm: Wow, very intresting but also very confusing. I would be happy to read your article somewhen on Ember Sherpa.

The irritation point for me is, how to initialize an object with injections without accessing __container__. I guess the Idee is to inject some singleton to the routes and controllers, and then inject propertys on that singleton to inject the target on that property instances, but I’m mostly confused.

But again thanks for your help.


#8

You probably don’t need 2 level of injections.

Setup your injections in initializers, there are several benefits to this:

  1. You get a high level overview of injections that you’re making
  2. You get access to app and container objects

If you can describe your use case more specifically, I could help you architect your injections.


#9

@tarasm: Thank u very much, i’m such a fan of 90% of ember, the problem is just that 10% that I totally dont understand.

I’ve multiple Projects with very similar use cases. One thing, is that directly after the user has logged in, he needs to select a location where he’s working, and from that moment I need the authentication token and and that location always when I call the backend.

Additionally I dont use a model framework, because ember-data is not stable and my backend is fully not standard, so I need a lot of code to get my models, often with multiple ajax calls. So I use normal subclasses of Object as models, with a common base class with a few little helper methods, and then use reopenClass to define the fetch functions.

Now I i try to find an elegant way to access the auth token and the location inside the fetch functions and the model instances, when I resolve some computed propertys with ajax calls.

For the fetch functions I can give the informations down from the route or controller, but I’ve no Idea for the computed properties. It seems very ugly to store both on every single model instance!

Currently I store everything directly on the App, but this seems just to be very ugly!

And, thats just one example, I’ve another Project with much more that globallike data, but its always the same, first select that, and then I need it for every ajax call.


#10

If you could create a JSBin that models where you got stuck, then I could refactor it with injections to show you how it works.


#11

The nice thing about all of the model hooks firing first is you can asynchronously shoot off a slew of model requests and make sure they are all resolved before hitting the setupController hooks. You can also just use this.modelFor in another model hook if you need access to the model of a parent model, during model hook time.

You can also create a controller during the application model hook and call it settings or something, and it will be available everywhere.

this.controllerFor(‘settings’).set(‘model’, {coolSettings:1});

Food for thought.


#12

@tarasm: Thank you very much for that offer, I’ve tried to simplify it and make a bin. the ugly point is the App.get('currentUser') and App.get('currentLocation'). Currently I’ve this dozen of times in my App.

Again, thank u very much.

@kingpin2k: Thanks for the answer.


#13

@krutius, I was away all weekend. I’m going to take a look at your code now. Also, I updated the search example app to fix the search keyword not being updated after going back.


#14

@krutius I started to refactor the app to use injections. I’m stuck on trying to figure out how the output determines the current location. Can you take a look at it? http://emberjs.jsbin.com/iHUTeNEp/60/edit


#15

@krutius are you still interested in this?


#16

@tarasm: Yes, sorry, I wasnt able to answer you. So, I’m investigating your refactoration.

I set the current location in the LocationRoute, App.set('currentLocation', this.get('location.location')); does the job.

And how can I access the User, where still App.get('currentUser.token'),is used (down in App.Item)

Btw, thanks for your helpagain! I’m starting understand the stuff… but still a long way.