AngularJS - 在所有其他控制器等完成后运行代码

时间:2014-08-11 19:41:01

标签: angularjs

我是Angular的新手,并且在内容加载时尝试进行一些页面阻止。此内容包括ajax个请求和其他一些内容,全部包含在控制器中。

以前,我在jQuery中使用$.Deferred处理一个简单的队列系统来处理这个问题,但是由于程序"流动的方式和#34;在Angular中从根本上说......不是那样的,我有点不知所措。我很难想到一种方法来告诉"我的程序/模块/应用程序"是的。我装完了。你现在已经完成了#34;。

有没有其他人经历过这个并发现了解决方案?

我的第一个想法是在每个控制器的末尾调用事件,但这产生了一些混合的结果。必须有一个更专业,更可靠的解决方案。

2 个答案:

答案 0 :(得分:1)

这样做的一种方法可能是创建一个服务并将其注入每个控制器,创建一个名为register的函数,该函数将承诺推送到服务中的数组中。然后,您可以监听所有承诺何时解决,并加载页面。

我认为你需要某种基本的计时器承诺来解决页面加载开始时的边缘情况,当控制器还没有注册他们的承诺时。

在控制器中,您将为整个控制器或单个函数注册您的承诺,由您决定,我将为每个控制器创建1个承诺,其中var deferred = $ q.defer()Scheduler.register(延迟。承诺),然后在所有其他承诺得到解决后解决延迟。

以下是一个简单示例:http://jsfiddle.net/4mf1pkLj/62/

当在调度程序

中解析所有承诺时,将调用$ window.ready()
 .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)
     }

答案 1 :(得分:1)

ngRouter模块允许使用resolve属性执行此操作。它会延迟视图渲染,直到加载所有数据。完整的文档可以在这里找到: https://docs.angularjs.org/api/ngRoute

基本示例(来自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'
            });
    });

在解决承诺延迟之前,您的视图不会呈现。