Cancel route using Sammy.js without affecting history

a 夏天 提交于 2019-12-04 03:40:29
John Papa

In case someone else hits this, here is where I ended up. I decided to use the context.setLocation feature of sammy to handle resetting the route.

sammy.before(/.*/, function () {
    // Can cancel the route if this returns false
    var
        context = this,
        response = routeMediator.canLeave();

    if (!isRedirecting && !response.val) {
        isRedirecting = true;
        toastr.warning(response.message); // toastr displays the message
        // Keep hash url the same in address bar
        context.app.setLocation(currentHash);
    }
    else {
        isRedirecting = false;
        currentHash = context.app.getLocation();
    }
    return response.val;
});

When using the code provided within the question and answer you have to notice that the route you cancelled will also be blocked for all future calls, routeMediator.canLeave will not be evaluated again. Calling a route twice and cancelling it depending on current state is not possible with this.

I could produce the same results as John Papa did when he used SammyJS on the SPA/Knockout course.

I used Crossroads JS as the router, which relies on Hasher JS to listen to URL changes "emitted" by the browser.

Code sample is:

hasher.changed.add(function(hash, oldHash) {
    if (pageViewModel.isDirty()){
        console.log('trying to leave from ' + oldHash + ' to ' + hash);

        hasher.changed.active = false;
        hasher.setHash(oldHash);
        hasher.changed.active = true;

        alert('cannot leave. dirty.');
    }
    else {
        crossroads.parse(hash);
        console.log('hash changed from ' + oldHash + ' to ' + hash);
        }
});

After revisiting an older project and having a similar situation, I wanted to share another approach, just in case someone else is directed here.

What was needed was essentially a modern "auth guard" pattern for intercepting pages and redirecting based on credentials.

What worked well was using Sammy.around(callback) as defined here: Sammy.js docs: Sammy.Application around(callback)

Then, simply do the following...

(function ($) {
    var app = Sammy("body");

    app.around(checkLoggedIn);

    function canAccess(hash) {
        /* access logic goes here */
        return true;
    }

    // Authentication Guard
    function authGuard(callback) {
        var context = this;
        var currentHash = app.getLocation();
        if (!canAccess(currentHash)) {
            // redirect
            context.redirect("#/login");
        }
        else {
            // execute the route path
            callback();
        }
    };

})(jQuery);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!