我正在使用AngularJS的$http服务来进行Ajax请求。
如何在Ajax请求执行时显示旋转GIF(或另一种类型的忙碌指示器)?
我在AngularJS文档中没有看到类似ajaxstartevent的东西。
我正在使用AngularJS的$http服务来进行Ajax请求。
如何在Ajax请求执行时显示旋转GIF(或另一种类型的忙碌指示器)?
我在AngularJS文档中没有看到类似ajaxstartevent的东西。
当前回答
只需使用ng-show和一个布尔值
不需要使用指令,不需要变得复杂。
下面是代码,可以放在提交按钮旁边,或者放在你想要旋转器的任何位置:
<span ng-show="dataIsLoading">
<img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" style="height:20px;"/>
</span>
然后在控制器中:
$scope.dataIsLoading = true
let url = '/whatever_Your_URL_Is'
$http.get(url)
.then(function(response) {
$scope.dataIsLoading = false
})
其他回答
只需使用ng-show和一个布尔值
不需要使用指令,不需要变得复杂。
下面是代码,可以放在提交按钮旁边,或者放在你想要旋转器的任何位置:
<span ng-show="dataIsLoading">
<img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" style="height:20px;"/>
</span>
然后在控制器中:
$scope.dataIsLoading = true
let url = '/whatever_Your_URL_Is'
$http.get(url)
.then(function(response) {
$scope.dataIsLoading = false
})
下面是一个使用指令和ng-hide的版本。
这将显示所有通过angular的$http服务调用的加载器。
在模板中:
<div class="装载机" </div>
指令:
angular.module('app')
.directive('loading', ['$http', function ($http) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.isLoading = function () {
return $http.pendingRequests.length > 0;
};
scope.$watch(scope.isLoading, function (value) {
if (value) {
element.removeClass('ng-hide');
} else {
element.addClass('ng-hide');
}
});
}
};
}]);
通过在元素上使用ng-hide类,可以避免使用jquery。
自定义:添加拦截器
如果你创建了一个加载拦截器,你可以根据条件显示/隐藏加载器。
指令:
var loadingDirective = function ($rootScope) {
return function ($scope, element, attrs) {
$scope.$on("loader_show", function () {
return element.removeClass('ng-hide');
});
return $scope.$on("loader_hide", function () {
return element.addClass('ng-hide');
});
};
};
拦截器:
例如:当响应时不显示旋转器。背景=== true; 拦截请求和/或响应设置$rootScope.$broadcast("loader_show");或rootScope。广播美元(“loader_hide”);
关于编写拦截器的更多信息
分享来自@bulltorious的精彩答案的我的版本,更新到更新的angular构建(我使用了1.5.8版本的代码),还加入了@JMaylin的想法,使用计数器来健壮地处理多个并发请求,以及选择跳过显示小于最小毫秒数的请求动画:
var app = angular.module('myApp');
var BUSY_DELAY = 1000; // Will not show loading graphic until 1000ms have passed and we are still waiting for responses.
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('busyHttpInterceptor');
})
.factory('busyHttpInterceptor', ['$q', '$timeout', function ($q, $timeout) {
var counter = 0;
return {
request: function (config) {
counter += 1;
$timeout(
function () {
if (counter !== 0) {
angular.element('#busy-overlay').show();
}
},
BUSY_DELAY);
return config;
},
response: function (response) {
counter -= 1;
if (counter === 0) {
angular.element('#busy-overlay').hide();
}
return response;
},
requestError: function (rejection) {
counter -= 1;
if (counter === 0) {
angular.element('#busy-overlay').hide();
}
return rejection;
},
responseError: function (rejection) {
counter -= 1;
if (counter === 0) {
angular.element('#busy-overlay').hide();
}
return rejection;
}
}
}]);
下面是我的实现,就像ng-show和请求计数器一样简单。
它使用一个新的服务为所有请求$http:
myApp.service('RqstSrv', [ '$http', '$rootScope', function($http, $rootScope) {
var rqstService = {};
rqstService.call = function(conf) {
$rootScope.currentCalls = !isNaN($rootScope.currentCalls) ? $rootScope.currentCalls++ : 0;
$http(conf).then(function APICallSucceed(response) {
// Handle success
}, function APICallError(response) {
// Handle error
}).then(function() {
$rootScope.currentCalls--;
});
}
} ]);
然后你可以根据当前调用的数量使用你的加载器:
<img data-ng-show="currentCalls > 0" src="images/ajax-loader.gif"/>
由于position:fixed的功能最近发生了变化,我很难将gif加载器显示在所有元素之上,所以我不得不使用angular内置的jQuery。
Html
<div ng-controller="FetchController">
<div id="spinner"></div>
</div>
Css
#spinner {display: none}
body.spinnerOn #spinner { /* body tag not necessary actually */
display: block;
height: 100%;
width: 100%;
background: rgba(207, 13, 48, 0.72) url(img/loader.gif) center center no-repeat;
position: fixed;
top: 0;
left: 0;
z-index: 9999;
}
body.spinnerOn main.content { position: static;} /* and whatever content needs to be moved below your fixed loader div */
控制器
app.controller('FetchController', ['$scope', '$http', '$templateCache', '$location', '$q',
function($scope, $http, $templateCache, $location, $q) {
angular.element('body').addClass('spinnerOn'); // add Class to body to show spinner
$http.post( // or .get(
// your data here
})
.then(function (response) {
console.info('success');
angular.element('body').removeClass('spinnerOn'); // hide spinner
return response.data;
}, function (response) {
console.info('error');
angular.element('body').removeClass('spinnerOn'); // hide spinner
});
})
希望这对你有所帮助。