我正在使用AngularJS和一些jQuery插件创建一个页面,其中angular-js控制器通过异步调用ajax调用一些servlet方法来初始化其模型。我想在第一个ajax调用开始时显示一个加载gif,并在最后一个ajax调用结束时隐藏它。
由于我不知道哪个是最后一次ajax调用,我不知道在哪里放置指令隐藏加载gif。我怎样才能实现这种行为?
我想要的代码示例:
myApp.controller("adminCtrl", function($scope, $http) {
$scope.initData1 = function() {
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
$scope.initData2 = function() {
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
$scope.initData3 = function() {
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
initData1();
initData2();
initData3();
}
我希望你能理解我的问题并知道如何实现这一目标。
答案 0 :(得分:2)
查看http://chieffancypants.github.io/angular-loading-bar/等进度条,可以在发出http请求时显示进度。它基本上是一个http拦截器,它跟踪http请求的数量,并相应地显示\隐藏进度条。
如果要解决此特定方案,可以使用$ q.all来实现此行为。首先,对于所有init *函数,返回http promise
$scope.initData1 = function() {
/* is this the first call? then show the gif */
var promise = $http(...);
promise.success(function(data) { // handle data});
return promise;
}
现在在调用代码中只需执行
//show animation
$q.all([$sope.initData1(),$sope.initData2(),$sope.initData3()]).then(function(responseArray) {
//hide animation
})
答案 1 :(得分:1)
如何:声明一个服务,您可以在其中注册待处理任务,然后声明它们已完成。
myApp.factory('pendingService', [function () {
var pendingTasksCount = 0;
return {
anyPending: function () {
return pendingTasksCount > 0;
},
registerNewTask: function () {
pendingTasksCount += 1;
return function declareTaskDone() {
pendingTasksCount -= 1;
}
}
};
}]);
然后在你的控制器中:
myApp.controller("adminCtrl", function($scope, $http, pendingService) {
// expose "any pending task" property in scope
$scope.showGif = pendingService.anyPending;
$scope.initData1 = function() {
var declareDone = pendingService.registerNewTask();
$http(...).success(function() {
// do stuff
// ...
declareDone();
});
};
$scope.initData2 = function() {
var declareDone = pendingService.registerNewTask();
$http(...).success(function() {
// do stuff
// ...
declareDone();
});
};
$scope.initData3 = function() {
var declareDone = pendingService.registerNewTask();
$http(...).success(function() {
// do stuff
// ...
declareDone();
});
};
initData1();
initData2();
initData3();
});
在HTML中:
<img src="mygifurl" alt="loading" ng-show="showGif()"/>
如果您需要此行为是本地行为而非全局行为,则可以使用同一工厂创建本地对象。
答案 2 :(得分:0)
您可以使用$.active来检查正在进行的活动ajax请求的数量。
myApp.controller("adminCtrl", function($scope, $http) {
$scope.initData1 = function() {
if($.active==0){
//this is the last active ajax request
}
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
$scope.initData2 = function() {
if($.active==0){
//this is the last active ajax request
}
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
$scope.initData3 = function() {
if($.active==0){
//this is the last active ajax request
}
/* is this the first call? then show the gif */
$http(...).success(function() { /* is this the last response received? then hide the gif */});
}
initData1();
initData2();
initData3();
}
答案 3 :(得分:0)
我会使用ngClass和一个计数器变量,例如
<html ng-app="testApp">
<head>
<style class="text/css">
.showing {
/* instead of this, you can add your gif here */
background: #f0f;
}
</style>
</head>
<body ng-controller="TestController">
<div class="test" ng-class="{'showing': count > 0 && count < 3}">
Count: {{count}}
</div>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
(function() {
var testApp = angular.module("testApp", []);
testApp.controller("TestController", function($scope) {
$scope.count = 0;
var timeout = function(t) {
// this represents your ajax callbacks
setTimeout(function() {
$scope.$apply(function() {
$scope.count = $scope.count + 1;
});
}, t * 1000);
};
timeout(1);
timeout(2);
timeout(3);
});
})();
</script>
</body>
</html>
您需要修改$ scope。$ apply函数上下文中的范围(在此特定示例中),否则您的视图将不会更新(有关发生这种情况的更多信息,请参阅:http://www.jeffryhouser.com/index.cfm/2014/6/2/How-do-I-run-code-when-a-variable-changes-with-AngularJS)。如果你使用promises,你可以避免这个问题,但我相信使用ngClass是修改视图的有角度的方法。