1

I am new to Angular, and am attempting to do some page blocking while content loads. This content includes ajax requests and some other things, all wrapped into controllers.

Previously, I was handling this with a simple queue system using $.Deferred in jQuery, but since the way the program "flows" in Angular is fundamentally ... not like that, I'm at a bit of a loss. I'm having a hard time thinking of a way to "tell" my program/module/app that "Yes. I am done loading. You are finished now".

Has anyone else experienced this and discovered a solution to it?

My first thought was to just call events at the end of each controller, but that has yielded some mixed results. There has to be a more professional, reliable solution.

2 Answers 2

1

ngRouter module permits to just do that with the resolve property. It will delay view rendering till all data is loadedThe complete doc can be found here: https://docs.angularjs.org/api/ngRoute

A basic example (from the doc):

angular.module('yourApp', ['ngRoute']);

angular.module('yourApp')
    .config(function($routeProvider) {
        $routeProvider
            .when('/Book/:bookId', {
                templateUrl: 'book.html',
                controller: 'BookController',
                resolve: {
                    // I will cause a 1 second delay
                    delay: function ($q, $timeout) {
                        var delay = $q.defer();
                        $timeout(delay.resolve, 1000);
                        return delay.promise;
                    }
                }
            })
            .when('/Book/:bookId/ch/:chapterId', {
                templateUrl: 'chapter.html',
                controller: 'ChapterController'
            });
    });

Your view will not be rendered before the promise delay is resolved.

Sign up to request clarification or add additional context in comments.

3 Comments

Hey, thanks for the response. I will give this a try when I get back to my office, this looks promising.
Is ngRoute different from angular-ui-router? The ui-router project is found here: github.com/angular-ui/ui-router
Yes. They serve the same goal. In my opinion, ui-router allows to achieve more than ngRoute. In particular: nested resolves. Their doc is well written, give it a shot and letme know if you need help
1

One way to do this might be to create a Service and inject it into each of the controllers, create a function called register which takes a promise pushes it into an array within the service. You could then listen for when all promises are resolved, and load the page.

I would imagine you would need some sort of basic timer promise as well to solve the edge case at the beginning of page load, when the controllers have yet to register their promises.

Within the controllers you would register your promise for the entire controller, or for individual functions, that is up to you, I would create 1 promise per controller with var deferred = $q.defer() Scheduler.register(deferred.promise), then resolve deferred when all other promises had been resolved.

Here's a simple example: http://jsfiddle.net/4mf1pkLj/62/

$window.ready() is called when all promises are resolved within scheduler

 .controller('OtherCtrl', ['$scope', '$q', 'scheduler',
     function($scope, $q, scheduler) {
         var differed = $q.defer()
         $scope.state = "waiting"
         //do some blocking ajaxy thing
         setTimeout(function() {
             differed.resolve()
             $scope.state = "ready"
         }, 5000);
         scheduler.register(differed.promise)
     }
 ])
 .service('scheduler', ['$http', '$q', '$window',
     function($http, $q, $window) {
         var promises = [];
         var finished = $q.defer().promise
         this.register = function(promise) {
             promises.push(promise)
             finished = wait()
          }

         function wait() {
             return $q.all(promises) 
         }

         function listen() {
             finished.then(function() {
                 //render your content
                 $window.ready() 
             })
         }

         //wait until everything is registered
         setTimeout(function(){listen()},200)
     }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.