8

I wanted to make the page to refresh automatically once a property of controller's model is updated.

I'm following this tip: How to reload current route in Ember.js?

So, I have an action method "runSimulation" in my controller, at the end of it I have this line :

this.send("sessionChanged");

In the associated route, I have:

actions: {
  sessionChanged: function() {
    console.log('YEAH');
    var transition = this.refresh();
    console.log(transition);
  }
},

renderTemplate: function(controller, model) {
  console.log('DINGDONG');
  var model = this.currentModel;
  if (model.simulation.params == undefined) {
    this.render('gobernador/crear-simulacion');
  } else {
    this.render('gobernador/show-simulacion');
  }
}

I could see that YEAH gets printed (meaning: the "sessionChanged" event sent by controller was successfully caught by the handler in the route object)..., but I don't see DINGDONG gets printed.

I'm using ember-cli, and I have the log transition enabled. I could see this in my javascript console:

Transitioned into 'gobernadores.gobernador.simulacion'

(which is expected). I suppose transitioning to "gobernadores.gobernador.simulacion" will cause the renderTemplate to be called (which for some reason is not happening here).

What might give us a clue here maybe the value of "transition" object returned from the execution of "refresh". In my case it gives:

{state: TransitionState, intent: C, **isActive: false,** router: Router, data: Object, resolvedModels: Object…} _visibleQueryParams: Objectdata: Object, handlerInfos: Array[4], intent: C, params: Object, pivotHandler: Class, promise: PromisequeryParams: Object, resolveIndex: 4,resolvedModels: Objectrouter: Routersequence: 4, state: TransitionStatetar, getName: "gobernador.simulacion"}

This "isActive" is false. Could it be the cause? If yes, why "isActive" is false?

I checked the API doc of Ember.Route::refresh ( http://emberjs.com/api/classes/Ember.Route.html#method_refresh ) ...

Refresh the model on this route and any child routes, firing the beforeModel, model, and afterModel hooks in a similar fashion to how routes are entered when transitioning in from other route. The current route params (e.g. article_id) will be passed in to the respective model hooks, and if a different model is returned, setupController and associated route hooks will re-fire as well.

So... maybe my question boil down to...: what conditions should be fulfilled for the refresh method of route to return a transition whose isActive is true?

I'm using ember 1.10.0

Thanks, Raka

UPDATE

I'm putting this link here..., just in case it gives some help in analysing the situation: http://blog.trackets.com/2013/02/08/router-request-lifecycle.html

Community
  • 1
  • 1
Cokorda Raka
  • 4,375
  • 6
  • 36
  • 54
  • http://emberjs.jsbin.com/ please – Andrey Mikhaylov - lolmaus Feb 15 '15 at 21:46
  • I'm seeing exactly the same issue. I have a route with no models and I want to refresh the page, causing a call to renderTemplate(). Unfortunately, if I use this.refresh(), it doesn't do anything. What needs to be done in order to trigger that call to renderTemplate() ? – Bogdan Zurac May 16 '15 at 08:42

2 Answers2

6

I don't know why refresh doesn't re-render, but why don't you just call renderTemplate yourself?

But more basically, this is an anti-pattern. You are essentially trying to manage your own subroutes each with its own template, by remembering which one you want and calling render yourself on the right one. But that's what the Ember router does for a living. Just create multiple subroutes--one for crear-simulation and one for show-simulation, and let Ember do the work.

Assuming you want to do things this way, swapping templates in and out, your approach is still not very Ember-like. You should use the templateName property on the route. Put an observer on it to call the default renderTemplate when it changes. Get rid of your custom renderTemplate

  • I understand your point about this being an anti-pattern. But there's a reason why there are some use cases where you don't want to use routes for this. In my case, I have 3 separate templates I want to render inside the index route, depending on the user authentication state. So obviously I don't want index or index/signed-in or whatever. So that's why I need to show different templates on the same route. That's why I need to refresh the state of the route in order for it to rerender the templates. Or like I initialy said, for it to call renderTemplate again, where the switch template resides – Bogdan Zurac May 16 '15 at 11:43
  • I tried renderTemplate manually; but as I need to do this from the application route, it didn't work for calls originating from other routes. Also, even if the trigger originated from index, I still need to do some initialization besides the actual rendering... So this doesn't work. I'm kind of getting tired of all these "it's not Ember-like" or "yeah, well, Ember doesn't work like that"... And it's not your fault, don't get me wrong. It's just that the framework is way too limited. I'm in charge of Android, Server and Web and only Ember causes trouble... Doesn't that kind of prove a point? – Bogdan Zurac May 16 '15 at 14:03
  • Regarding the templateName property, I'm not familiar with that. I presume you would set the property to "index" or "index-signed-in" and it would just trigger the renderTemplate automatically and render the aforementioned template instead? – Bogdan Zurac May 16 '15 at 14:05
  • Never mind, got it working by doing multiple hops between controllers and routes and finally calling renderTemplate() manually every time. Not really ok, but then again what is ok in Ember...? – Bogdan Zurac May 19 '15 at 10:07
  • I think torazaburo's approach is the cleanest in this context. – Cokorda Raka May 21 '15 at 21:08
-1

What I ended up doing was, like torazaburo initially said, calling renderTemplate() manually. You can do so by returning true inside your sessionChanged action in the controller, if you intend to implement it there instead. This will bubble the action to your route. Then inside your route, just implement the same sessionChanged action (like you already did) and call this.renderTemplate().

What I also noticed is that when the user is not on the specified route, the action won't bubble anymore to the route from the controller (even if you transition to it), thus your route action won't be called anymore. In this case, apparently setupController() is called instead. Thought it was worth mentioning.

Lynn Crumbling
  • 12,985
  • 8
  • 57
  • 95
Bogdan Zurac
  • 6,348
  • 11
  • 48
  • 96
  • 2
    Your edit was rejected because it altered the other user's answer. It's absolutely correct to either post a comment to their answer, or, as you've done, add a new answer if it brings enough new information to the table. – Lynn Crumbling May 19 '15 at 17:13
  • The point of the edit was to complete his answer and not create an entirely new answer that is practically based on another answer. It doesn't make sense. It also supports his answer in accordance to the bounty. But hey, whatever floats your boat, right? Also, if one would deny an edit, common sense would tell one to also provide an explanation as to why that happened. But no, it's easier to just deny and go on with your day. – Bogdan Zurac May 19 '15 at 17:17
  • @Andrew "The point of the edit was to complete his answer" - Typically this is done by commenting on the answer, asking the poster to complete it. – vaultah May 19 '15 at 17:20