I'm linking from a child route to a parent route.
In this example, I'm linking from a 'category' child page to the parent 'availability' page.
I understand that the Ember Router skips the model hook on links/transitions to a parent route.
I'm just looking for the beforeModel hook to be called on the parent route.
It does this all well and good, but it goes to the availability.index subroute, which is not where my beforeModel hook is written (see console output). My beforeModel hook is written in the availability route.
I could duplicate or move code to the index subroute, but I really don't understand why Ember is doing this. Putting my hooks in the availability route works all the time except for this case.
Here's my router pattern:
this.resource('availability', function() {
this.resource('category', {path: '/category/:category'});
})
Category Template
{{#link-to 'availability'}}
<span>Go Back</span>
{{/link-to}}
Console transition output:
Attempting transition to availability
ember.js?body=1:15374 Transition #5: availability.index: calling beforeModel hook
ember.js?body=1:15374 Transition #5: availability.index: calling deserialize hook
ember.js?body=1:15374 Transition #5: availability.index: calling afterModel hook
ember.js?body=1:15374 Transition #5: Resolved all models on destination route; finalizing transition.
ember.js?body=1:15374 Transitioned into 'availability.index'
ember.js?body=1:15374 Transition #5: TRANSITION COMPLETE.
Related
I'm trying to fire the Lifecycle events from Navcontroller as described in the Api docs
The problem is, that I just can fire these events by a parent component, sub components does not fire . Is there something I have to add/change, when I want to add these events to Subcomponents ?
(I think there is no code needed to undestand the problem)
System:
Ubuntu 16.04 /
Node 6.7.x /
npm 3.10.x /
ionic 2 rc0
An inner component knows nothing about Ionic lifecycle events. Ionic/pages will not notify inner components about loading, become the active page, etc. If you need your inner component to do something based on lifecycle events, tie the parent lifecycle event with the inner component using Angular's #ViewChild decorator.
In parent component get a reference to the child component using #ViewChild as explained here. Then, inside the parent lifecycle event, call a public function defined in child component.
Hope it helps,
Xavi
I have the following situation to handle in ember :-
I have to transition to a route which has a model hook. The model hook returns a promise. (Say route A -> route B, Route B has a model hook returning a promise)
While the model hook in B is running, the loading route is entered(for showing "please wait" type msg to user).
In case the model hook in B fails, I need to transition back to route A. I handle the error action in route B.
The problem is, while handling error action in route B, the previous route is not always route A. It can be from other another route too.
I tried the possible workarounds, but they didn't work out for me:-
1) Using window.history.back() - This fails because Route B isn't entered yet, because the model hook promise failed. So I get the previous route of Route A.
2) Using this.controllerFor('application').get('currentRouteName') - This gives the loading route (While transitioning from Route A to Route B, intermediate route 'loading' is rendered).
I can use a conditional check with query Params, but I feel this is not efficient as I have to check for many conditions.
I simply wish to return to the route that invoked Route B.
Pardon me if I missed out on anything.
Sample project : Twiddle
I reopened Ember.Route to catch all transitions and save the current route name in a application controller property. When error action is called, i transition to the route saved in that property. Routes with dynamic segments will need extra handling.
Another Method :
In your router.js,
var Router = Ember.Router.extend({
location: config.locationType,
didTransition : function(infos){
this._super(infos);
var appController = this.container.lookup('controller:application');
var crn = infos[infos.length - 1].name;
if(appController && crn!=='loading' && crn!=='error'){
Ember.set(appController,'myRouteName',crn);
}
}
});
I am not sure if there is any in built solution.
I have this router setup
this.route('dashboard', function () {
this.route('numbers');
this.route('workspaces', function () {
this.route('workspace', {path: '/:wid'});
});
dashboard.workspaces is a link in navigation bar. When you click it loads dashboard.workspaces.workspace and immediately redirects to first subnav. I do it like this:
export default Ember.Route.extend({
model: function() {
return this.modelFor('dashboard');
},
afterModel: function(model) {
this.transitionTo('dashboard.workspaces.workspace', model.get('workspaces.firstObject.id'));
}
}
It's all good except when I'm already on dashboard.workspaces.workspace route and click dashboard.workspaces then "afterModel" hook is not called and I end up on dashboard.workspaces, which is unwanted empty page. Are there other hook that would be always called? I have already tried "activate" and few others with no luck.
Would be also nice to be able to save last subnav transition and redirect to in when click on main nav.
So it's important to think of the router as a stack. As you visit routes you push a route on/off the stack. An item that is being pushed on or off the stack will have events fired correlating to the transition at hand.
In your particular case, the current implementation has two issues. The one issue you've already mentioned, when you pop off children routes the parent route doesn't fire any events. The second issue would occur under these circumstances.
Navigate to workspaces /workspaces (it redirects to the first workspace /workspaces/1)
Navigate to the second workspace /workspaces/2
Refresh the page while on /workspaces/2 (while it's in the afterModel hook of workspaces it redirects to the first workspace /workspaces/1)
So the easiest way to handle this is to create a child route under the workspaces route whose sole purpose is to redirect to the first workspace.
this.route('dashboard', function () {
this.route('numbers');
this.route('workspaces', function () {
this.route('first');
this.route('workspace', {path: '/:wid'});
});
Remove the afterModel logic from the workspaces route and put it in the workspaces.first route.
export default Ember.Route.extend({
redirect: function() {
var first = this.modelFor('workspaces').get('firstObject');
this.transitionTo('dashboard.workspaces.workspace', first);
}
}
Now in your template, instead of ever pointing to workspaces you would point to workspaces.first.
{{link-to 'Workspaces' 'dashboard.workspaces.first'}}
Now when you are in the dashboard and click it, it will push on the workspaces route into the stack execute its hooks. It will then push the first route onto the stack and execute its hooks. The hooks of the first route will cause it to pop the first route off the stack and push the workspace route onto the stack. When you try to click the workspaces route again it will pop workspace off the stack and then push first back onto the stack which will then again execute its hooks.
Example: http://emberjs.jsbin.com/cipawapali/edit?html,js,output
May be a bit late, but for anyone looking for a solution to this empty white page as I was.
Ember provides an implicit/hidden route, that can be used instead of creating a new one, which is pretty good for this.
In this question's case it would be DashboardWorkspacesIndexRoute, no need to declare it in the router, just add the route file with the redirection you want
export default Ember.Route.extend({
redirect() {
let first = this.modelFor('workspaces').get('firstObject');
this.replaceWith('dashboard.workspaces.workspace', first);
}
}
You can then use {{link-to 'Workspaces' 'dashboard.workspaces'}} and it will retain the active class while still redirecting every time.
For more information, here's the source.
After upgrading from 1.10 to 1.13.2 my application stopped working on IE8 - it doesn't load the main route and doesn't start the application correctly. There are no exceptions thrown. Below is the log from IE8:
DEBUG: -------------------------------
DEBUG: Ember : 1.13.2+616f7a7e
DEBUG: jQuery : 1.11.1
DEBUG: -------------------------------
Processing last blocks: 0ms
Timer "Processing last blocks" does not exist.
Attempting URL transition to /
generated -> route:application, [object Object]
generated -> route:index, [object Object]
Preparing to transition from '' to ' index'
Transition #0: application: calling beforeModel hook
Transition #0: application: calling deserialize hook
Transition #0: application: calling afterModel hook
Transition #0: index: calling beforeModel hook
Transition #0: index: calling deserialize hook
Transition #0: index: calling afterModel hook
Transition #0: Resolved all models on destination route; finalizing
transition.
generated -> controller:application, [object Object]
generated -> controller:index, [object Object]
Transitioned into 'index'
Transition #0: TRANSITION COMPLETE.
And the same log from Chrome:
DEBUG: -------------------------------
DEBUG: Ember : 1.13.2+616f7a7e
DEBUG: jQuery : 1.11.1
DEBUG: -------------------------------
1360
Processing last blocks: 0.009ms
Ember Inspector Active
Attempting URL transition to /
generated -> route:events.index Object {fullName: "route:events.index"}
Preparing to transition from '' to ' events.index'
Transition #0: application: calling beforeModel hook
Transition #0: application: calling deserialize hook
Transition #0: application: calling afterModel hook
Attempting transition to events.country
Transition #0: events.index: transition was aborted
Transition #1: events: calling beforeModel hook
Transition #0: detected abort.
Transition #1: events: calling deserialize hook
Transition #1: events: calling afterModel hook
Transition #1: events.country: calling beforeModel hook
Transition #1: events.country: calling deserialize hook
Transition #1: events.country: calling afterModel hook
Transition #1: Resolved all models on destination route; finalizing
transition.
generated -> controller:application Object {fullName: "controller:application"}
Deprecations were detected, see the Ember Inspector deprecations tab for more details.
Transitioned into 'events.country'
Transition #1: TRANSITION COMPLETE.
Before the upgrade everything worked fine. Any ideas?
Considering this example: http://emberjs.jsbin.com/hecewi/1/edit?html,js,output
The docs state that an action will be searched for on the controller first (which works in the example e.g. by pasting the actions hash into the IndexController), then on the current route and then along its parent routes until it hits ApplicationRoute. I'd expect the testCamel action in the example to be triggered then, but instead there is an error about the route did not get handled. How to do it right?
The code to trigger an action is indeed correct. It's just an unfortunate chosen example. Since your route will initialize the controller, the route itself is probably not completely initialized by the time the action is sent. If you, for example, schedule the action to be triggered in the following run loop, it works perfect:
http://emberjs.jsbin.com/yaseva/1/edit