0

Hi I would like to be able to delay the splash of my app for a bit here is what I mean.

This is my shell view:

<div>
<!-- ko compose: { view : header }-->
<!--/ko-->
<!-- ko compose: { view : content }-->
<!--/ko-->

This is my shell viewmodel:

define(['plugins/router', 'services/dataService' , 'models/appViewModels'],
    function (router,dataService , appViewModels) {

        var vm = {
            header: ko.observable(),
            content: ko.observable(),
            activate: activate
        };

        function activate() {
            setActivePage();
        }


        function setActivePage() {
            $.when(dataService.account.isAuthenticated())
                .done(function(isAuthenticated) {
                    setDefaultDisplayPage(isAuthenticated)
                }).fail(function(data) {
                    alert(data);
                });
        }

        function setDefaultDisplayPage(isAuthenticated) {
            if (isAuthenticated) {
                setHeaderAndContentObservables(appViewModels.header.generalHeader, appViewModels.content.homeContent);
            } else {
                setHeaderAndContentObservables(appViewModels.header.loginHeader, appViewModels.content.loginContent);
            }
        }
}

The reson I am using observables instead of a string representation of a path for my view is because in my shell I am deciding if I should sent my user on the login or homepage .

This works perfectly except for one thing in the time that it takes to get the isAuthenticated property from the server the splash screen dissapears and the user is left waiting on a blank page until the data is recieved.

Now I could try getting the data in the main.js file and cache it but I figure main.js should have only app configuration responsibility.

Is there any way to make the call to the server for the data before the shell actually get's binded and the splash screen dissapears?

Nistor Alexandru
  • 5,309
  • 9
  • 46
  • 71
  • 1
    You can return a promise from shell in your activate call. It looks like you are almost there, but you aren't returning it. The Durandal lifecycle allows you to return that promise and it will wait for the promise to resolve before it finishes 'loading'. I am sure you can get it to work with the jQuery promise, but if you were using Q.js you could use something like return q.All(); – PW Kad Jan 26 '14 at 15:18

1 Answers1

2

I agree with what PW Kad suggested. Durandal is packed with Q.js. I had the same scenario [Check if the user is authenticated=> Load user menus from database through Durandal router which returns a promise => Load the content] However, I can't see the router in your code.

Anyway, In the activate method you could do something like this:

  var vm = {
            header: ko.observable(),
            content: ko.observable(),
            isAuthenticated: ko.observable(false),
            activate: activate
        };

function activate() {

            return Authenticate()
                 .then(setDefaultDisplayPage)
                 .fail(failed);
        }
function Authenticate() {
// pass an observable as a parameter to your function 
                dataService.account.isAuthenticated(isAuthenticated);
                return Q.resolve();
                }
       function setDefaultDisplayPage() {        
        if(isAuthenticated()) {
    setHeaderAndContentObservables(appViewModels.header.generalHeader,appViewModels.content.homeContent);
}
        else { setHeaderAndContentObservables(appViewModels.header.loginHeader,appViewModels.content.loginContent);
        }
    }
    function failed(){
// failure code goes here
}

This way, your viewmodel won't get binded until data is fetched from the server.

Adel Sal
  • 718
  • 5
  • 16