2013-10-15 44 views
1

我有一个加载图标设置我的页面上,看起来像这样:如何使用AngularJS跟踪许多异步过程的开始和结束?

<div class="loading-mask" 
    data-ng-show="action != null"> 
    <span>{{action}} ...</span> 
</div> 

当我设置$ scope.action的消息出现在装填箱。

加载我的页面时,我有许多不同的异步进程获取数据。例如,我有:

getUserProfiles: function ($scope) { 
     var url = '/api/UserProfile/GetSelect'; 
     $http({ method: 'GET', url: url }) 
      .success(function (data, status, headers, config) { 
       $scope.option.userProfiles = data; 
      }) 
      .error(function (data, status, headers, config) { 
       alert("Error: No data returned from " + url); 
      }); 
    }, 

和:

getSubjects: function ($scope) { 
     var url = '/api/Subject/GetSelect'; 
     $http({ method: 'GET', url: url }) 
      .success(function (data, status, headers, config) { 
       $scope.option.subjects = data; 
      }) 
      .error(function (data, status, headers, config) { 
       alert("Error: No data returned from " + url); 
      }); 
    }, 

我怎样才能让这个第一,这些异步过程会导致出现“正在加载”消息,最后的异步处理的原因装载箱不再显示。注意此时我不关心错误消息。我只是希望加载在所有事情完成时不显示。

+0

是不是重复http://stackoverflow.com/questions/15033195/showing-spinner-gif-during-http-request-in-angular? –

+1

会间接承诺描述[这里](http://stackoverflow.com/questions/19290196/angular-how-to-deal-with-unavailable-urls-requested-by-http-get-or-http-jsonp)帮帮我? –

回答

2

要扩展devmiles的说法,但要处理多个异步函数,您需要在要调用的第一个函数上设置加载标志。即:

getUserProfiles: function ($scope) { 
    $scope.loading = true; 
    var url = '/api/UserProfile/GetSelect'; 
    $http({ method: 'GET', url: url }) 
     .success(function (data, status, headers, config) { 
      $scope.option.userProfiles = data; 
     }) 
     .error(function (data, status, headers, config) { 
      alert("Error: No data returned from " + url); 
     }); 
}, 

然后你会想换你的每一个异步函数的一个承诺,就像这样:

getUserProfiles: function ($scope) { 
    var deferred = $q.defer(); 
    $scope.loading = true; 
    var url = '/api/UserProfile/GetSelect'; 
    $http({ method: 'GET', url: url }) 
     .success(function (data, status, headers, config) { 
      $scope.option.userProfiles = data; 
      deferred.resolve(); 
     }) 
     .error(function (data, status, headers, config) { 
      alert("Error: No data returned from " + url); 
      deferred.reject(); 
     }); 
    return deferred; 
}, 

然后,您可以调用$ q.all您所有的异步函数,和将发生的这个成功回调一旦所有异步函数已经解决:

$q.all([getUserProfiles, getSubjects]).then(function() { 
    $scope.loading = false; 
} 

这意味着一旦所有的功能已经解决,负荷将被设置为false。

注意:如果要访问回调数据,可以将其作为“deferred.resolve(x)”的参数传入,然后在$ q.all回调中,它将作为函数(x){用x做某事}。

希望这会有所帮助!

编辑:不要忘记将角度的诺言服务$ q传递给你的函数所在的控制器。

+0

http://stackoverflow.com/users/2515902/b-cotter我喜欢这个答案,但我怎么知道什么时候调用$ q.all? –

+0

你不明确地称它,你只是声明它。因此,我的意思是说,当所有这些事情都发生时,做'this','this'是你放入的.then(function(){xxxx})。因此,您不必担心调用它,只需将它放在与两个异步方法相同的控制器中,并且当它们成功完成时(这是发生deferred.resolve()的地方),它们将让$($) q服务知道。一旦你的所有承诺都解决了,$ q就会调用你的回调函数,并将加载设置为false。 希望这可以帮助,让我知道如果有什么我可以澄清。 –

0

当您的控制器正在实例化时,只需设置一些布尔标志,并在成功/错误功能中重置此标志。

.controller('MyCtrl', function ($scope) { 
    $scope.isLoading = true; 
    $http({ method: 'GET', url: url }) 
      .success(function (data, status, headers, config) { 
       $scope.option.subjects = data; 
       $scope.isLoading = false; 
      }) 
      .error(function (data, status, headers, config) { 
       alert("Error: No data returned from " + url); 
       $scope.isLoading = false; 
      }); 
}); 

使用ng-show加上此标志来显示您的加载方式。

+0

问题是我在设置时发生了多个加载。如果另一个仍在加载,则设置isLoading = false时不起作用。 –

+0

承诺是很酷的,但是对于更简单的方法,您可以设置isLoading = 2,并在每次完成时递减它。 –