如何使用AngularJS跟踪许多异步进程的开始和结束?

时间:2013-10-15 12:18:46

标签: 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);
            });
    },

如何进行此操作以便第一个异步进程导致出现“正在加载”消息,最后一个异步进程导致加载框不再显示。请注意,此时我并不关心错误消息。我只是想在一切都完成时不显示加载。

2 个答案:

答案 0 :(得分: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);
        });
},

然后你会希望将每个异步函数包装在一个promise中,如下所示:

   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。

注意:如果要访问回调数据,可以将其作为&#34; deferred.resolve(x)&#34;的参数传递,然后在$ q.all回调中传递,它将作为函数(x){对x做一些事情}。

希望这有帮助!

编辑:不要忘记将有角度的承诺服务$ q传递给你的职能所在的控制器。

答案 1 :(得分: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来显示您的加载内容。