Breeze going faster than the shell togglespinner

2019-09-16 17:15发布

                    Hi all,

My environment : vwd 2013, sql server 2012, project template : Hot towel - Angular (by John Papa), BreezeJs, Breeze.WebApi2, Breeze.ContextProvider.EF6, Entity-Framework ADO .Net 6.

I'm making a little Web app SPA, everything used to work correctly as long as I instanciate a new BreezeManager before every Web API call with entityManagerFactory, all the web api calls are done in 2 services datacontext and authenticationservice (of my own development). Then I discover that app was going much faster with a global BreezeManager instanciated once at the start of the 2 services, and use it for all the web api calls. But apparently it's going too fast so that "Busyindicator" / togglespinner to be started, so the page appears white before being populated with data, the togglespinner and its waiting message are not displayed while the treatment.

I've well seen, in the shell.js, that the togglespinner is started at every route's change and stopped at every controller succesfull activation.

So to start correctly the app, I have created an intermediate page 'await.html' and its vm 'await.js' that's only redirecting to a new page, this page is at the root of routes.

So it should be working like this, the web app is started, going to 'await.html', then redirection to a new page, the togglespinner is started, then promise of this new page is correctly terminated and the togglespinner is stopped, but it doesn't work.

I remind you, that with a new BreezeManager for every web api call, it works.

My page is constituted (as originally) with a dynamic sidebar menu, a dynamic topnav and the page itself, in these 3 components there are web api calls, for the sidebar and topnav the web api calls are done only at the app start, maybe there is a problem of concurrency with these 3 components ?

Here is some code :

datacontext.js :

    (function () {
        'use strict';

        var serviceId = 'datacontext';
        angular.module('app').service(serviceId, ['common', 'config', 'model', 'entityManagerFactory', 'breezePartialMapper', datacontext]);

        function datacontext(common, config, model, entityManagerFactory, breezePartialMapper) {
            var $q = common.$q;
            var manager = entityManagerFactory.newManager();
            var entityNames = model.entityNames;
    .
    .
    .
        function getUser() {
            //var manager = entityManagerFactory.newManager();
            var query = breeze.EntityQuery.from('GetUser').expand("Membership").withParameters({ UserId: user.userId });
            //var resLoc = getLocal(query);

            return $q.when(manager.executeQuery(query)
            .then(successCallback)
            .catch(failCallback)     // same as 'then(null, failCallback)'
            .finally(finalCallback) // sort of like 'then(finalCallback, finalCallback)'
            );
        }
.
.
.
        function successCallback(data) {
            return data.results;
        }
.
.
.
}

In the displayed page vm :

(function () {
    'use strict';
    var controllerId = 'FGHomePage';
    angular.module('app').controller(controllerId, ['common', 'datacontext', FGHomePage]);

    function FGHomePage(common, datacontext) {
        var getLogFn = common.logger.getLogFn;
        var log = getLogFn(controllerId);
        var $q = common.$q;

        var vm = this;
        vm.title = 'FGHomePage';
        vm.user;
        vm.imageUrl = "";

        activate();

        function activate() {
            var promises = [getUser()];
            common.activateController(promises, controllerId)
                .then(function () { log('Activated Admin View'); });
        }

        function getUser() {
            datacontext.user.userId = 1;
            return datacontext.getUser()
                .then(function (data) {
                    vm.user = data[0];
                    if (vm.user.fileExtension != "" && vm.user.fileExtension != null) {
                        vm.imageUrl = vm.user.userName.replace(" ", "_") + "." + vm.user.fileExtension;
                    }
                    else {
                        vm.imageUrl = "NonImage.gif";
                    }
                    //return $q.when(vm.user);
                    return vm.user;
                });
        }
    }
})();

Do you see something wrong in the code ?

Thanx for your help.

1条回答
一纸荒年 Trace。
2楼-- · 2019-09-16 17:51

I found a solution to this problem. I had to change the event starting the togglespinner. Now to start the togglespinner I've choosen the beginning of activatecontroller before the resolution of promises. For this : - in config.js : I add the start activate event :

var events = {
    controllerStartActivate: 'controller.startActivate',
    controllerActivateSuccess: 'controller.activateSuccess',
    spinnerToggle: 'spinner.toggle'
};

and :

//#region Configure the common services via commonConfig
app.config(['commonConfigProvider', function (cfg) {
    cfg.config.controllerStartActivateEvent = config.events.controllerStartActivate;
    cfg.config.controllerActivateSuccessEvent = config.events.controllerActivateSuccess;
    cfg.config.spinnerToggleEvent = config.events.spinnerToggle;
}]);
//#endregion

Then in common.js I broadcast this event at the beginning of activateController :

    function activateController(promises, controllerId) {
        $broadcast(commonConfig.config.controllerStartActivateEvent);
        return $q.all(promises).then(function (eventArgs) {
            var data = { controllerId: controllerId };
            $broadcast(commonConfig.config.controllerActivateSuccessEvent, data);
        });
    }

Then in shell.js I start the togglespinner on this event :

$rootScope.$on(events.controllerStartActivate,
    function (data) { toggleSpinner(true); }
);

In this way the togglespinner will be started at the beginning of activatecontroller and stopped after the resolution of the promises of the controller. If there are several controllers activated at (almost) the same time, for each a togglespinner will appear (as there are instances of the same togglespinner we don't see a difference visually). This last case doesn't appear often.

Hope this will help, if you see an improvement...

查看更多
登录 后发表回答