I have the following:
function activate(routeData) {
// make dataservice call, evaluate results here. If condition is met, reroute:
if (true){
router.navigateTo("#/someRoute");
}
alert ("should not be shown");
}
The alert is getting hit however, and then the view changes.
How do I fully navigate away from the current item and prevent any further code in that vm from being hit?
Update:
I tried using guardroute
but I have to activate the viewModel to call the dataservice that returns the data that determines whether or not I should re-route. Using guardroute totally prevents the dataservice from getting called (since nothing in the activate function will get hit).
I also tried returning from the if
block but this still loads the view / viewAttached / etc so the UX is glitchy.
Here's @EisenbergEffect answer to a quite similar discussion in google groups.
Implement canActivate on your view model. Return a promise of false,
then chain with a redirect.
You might want to give @JosepfGabriel's example (discussion) a try in Durandal 1.2. Check the correct router
syntax for your Durandal version, you might have to substitute it with something like router.navigateTo("#/YourHash", 'replace')
.
canActivate: function () {
return system.defer(function (dfd) {
//if step 2 has a problem
dfd.resolve(false);
})
.promise()
.then(function () { router.navigate("wizard/step1", { trigger: true, replace: true }); });
}
However this is NOT working in Durandal 2.0 and there's a feature request https://github.com/BlueSpire/Durandal/issues/203 for it.
The following worked for me in Durandal 2.0:
canActivate: function() {
if(condition)
return {redirect: 'otherRoute'};
return true;
}
activate: // Do your stuff
It's mentioned in the documentation: http://durandaljs.com/documentation/Using-The-Router.html
You can't call redirect into the active method.
You can override the guardRoute method from router, to implement redirections.
You can do somehting like that:
router.guardRoute= function(routeInfo, params, instance){
if(someConditios){
return '#/someRoute'
}
}
You can return a promise, true, false, the route to redirect... You can find more information about that in the next link: http://durandaljs.com/documentation/Router/
Rainer's answer was pretty good and works for me adding this small fix.
Inside the then() block simply call the navigation like this
setTimeout(function() { router.navigateTo('#/YOUR DESTINATION'); }, 200);
that should fix your problem. The setTimeout does the trick. Without it the newly navigated page catches the old NavigationCancel from the previous one.
Adding a return in your if (true) block should fix this.
function activate(routeData) {
if (true){
router.navigateTo("#/someRoute");
return;
}
alert ("should not be shown");
}