Durandal 2.0 shell.js not running in every view

497 Views Asked by At

I upgraded my application to Durandal 2.0. My app is modeled after HotTowel, with a main.js and a shell.js. I thought that shell.js ran on every view, however it is not. My shell.js contains my security code, which of course has to be ran on every view. How can i force shell.js to run on every view?

Here is an excerpt from main.js-

 define(['durandal/app', 'durandal/viewLocator', 'durandal/system', 'plugins/router', 'services/logger'],
function (app, viewLocator, system, router, logger) {

system.debug(true);

app.configurePlugins({
    router: true,
    dialog: true,
    widget: {
        kinds: ['expander']
    }
});

app.start().then(function () {
    toastr.options.positionClass = 'toast-bottom-right';
    toastr.options.backgroundpositionClass = 'toast-bottom-right';

    viewLocator.useConvention();
    router.makeRelative({ moduleId: 'viewmodels' });

    // Adapt to touch devices
    //Show the app by setting the root view model for our application.
    app.setRoot('viewmodels/shell');

    return router.map([
            { route: 'home', moduleId: 'home', title: 'home', title: 'Home', nav: true },
            { route: 'CAApproval', moduleId: 'CAApproval', title: 'CA Approval', nav: true }
    ]).activate();

});

an excerpt from shell.js-

 define(['durandal/system', 'plugins/router', 'services/logger', 'services/SecurityDataService'],
function (system, router, logger, SecurityDataService) {

    var HasAccess = ko.observable();
    var test = ko.observable('it works');


    router.map('About', 'About', 'About', false);
    router.map('Help', 'Help', 'Help', false);

    var vm = {
        activate: activate,
        router: router,
        User: ko.observable(),
        showAbout: 'About',
        showHelp: 'Help',
        test: 'itworks'
    };
    return vm;

    function showAbout() {

       router.navigate('About'); // should show about view
    }

    function showAbout() {

       router.activate('Help'); // should show about view
    }

    function activate() {
        alert("here");
        $.when(
            $.ajax({
                url: '/api/security/CheckSecurity/',
                dataType: 'json',
                success: function( data ) {
                    strHasAccess = "";
                    if (typeof (data) == "string") {
                        strHasAccess = $.parseJSON(data);
                        HasAccess = strHasAccess[0].HasAccess;
                        vm.User = strHasAccess[0].UserName;
                        $('#spnUserName').text(vm.User);
                    } else {
                        HasAccess = false;
                    }

                    return strHasAccess;
                },
                error: function (data) {
                    amplify.store("ErrorDetails", data.responseText);
                    log('Error!', null, true);

                    //return router.activate('ErrorPage'); // should show details page of a particular folder

                }
            })
        ).then(function (HasAccess) {

            if (strHasAccess[0].HasAccess == true) {
                router.buildNavigationModel();
                vm.User = strHasAccess[0].UserName;
               router.navigate('home');

            }
            else {
                 router.map([
            { route: 'AccessDenied', moduleId: 'AccessDenied', title: 'AccessDenied', title: 'AccessDenied', nav: true }
                ]).activate

                 router.navigate('AccessDenied');
                log('Access Denied!', null, true);
            }
        });
    }

    function log(msg, data, showToast) {
        logger.log(msg, data, "shell.js", showToast);
    }
});
1

There are 1 best solutions below

1
Binu On

Shell is composed once and views are injected into the shell as you navigate from one view to another. One way to check for some condition before you navigate to a view is to have guard route.

app.start().then(function() {

    viewLocator.useConvention();

    app.setRoot('shell/shell', 'entrance');

    router.guardRoute = function (instance, instruction) {
        //auth check here
    };
});

Another approach could be to have canActivate() in each view(model) to check something, and send user elsewhere when a condition is not met.