How to handle / ignore a bad route with durandal?

2019-02-11 01:15发布

问题:

I'm trying to conditionally block a route from being accessed. I think this can be done with guardRoute: http://durandaljs.com/documentation/Router/

function guardRoute(routeInfo, params, instance) : object - Before any route is activated, the guardRoute function is called. You can plug into this function to add custom logic to allow, deny or redirect based on the requested route. To allow, return true. To deny, return false. To redirect, return a string with the hash or url. You may also return a promise for any of these values.

I'm not sure how to specify which route should be accessed though, or how to re-route to another view if I need to deny access. Can someone post an example of its use in this manner?

回答1:

You should use guardRoute before activating the router e.g. in shell.js. The example is taken from a Durandal 2.0 alpha site. AFAIK guardRoute hasn't changed from 1.2, but setting a breakpoint will allow you to figure out what arguments are passed in for 1.2. As a general rule, return true to allow navigation, false to prevent it and a hash or url value to redirect.

define(['plugins/router'], function (router) {

    // Redirecting from / to first route in route.map
    router.guardRoute = function(routeInfo, params, instance){
        if (params.fragment === ''){
            return routeInfo.router.routes[0].hash;
        }
        return true;
    };
    ...    

    return {
        ...
        router: router,
        activate: function () {
            router.map([
               ---
            ]);

            return router.activate();
        }
    };
});


回答2:

I am a newbie to durandaljs 2.0 having only used it for a couple of weeks so this was one of my first stumbling blocks. see my code below

router.guardRoute = function (routeInfo, params, instance) {
    var insecureRoutes = ['login', 'terms','signup','password'];
    if ($.inArray(params.fragment, insecureRoutes) || mymodule.isAuthenticated()) {
        return true;
    } else {
        return 'login/' + params.fragment;
    }
};

I also define a route for the login page like this

{ route: 'login/(:returnroute)', moduleId: 'viewmodels/login', nav: false },

This allows you to optionally specify a return rout so that after login you can redirect the user to where ever it is they were initially trying to go to. I hope it helps someone