Durandal: How to route away from current view with

2019-03-21 15:52发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

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/



回答4:

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.



回答5:

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");
}