Реализация загрузки спиннера с использованием httpInterceptor и AngularJS 1.1.5
Я нашел пример загрузки спиннера для вызовов http/resource здесь на SO:
- Установите переменную rootScope в httpIntercept (Plunker: http://plnkr.co/edit/32Mh9UOS3Z4vnOtrH9aR?p=preview)
Как видите, реализация работает (с использованием AngularJS 1.0.5). Однако, если вы измените источники на AngularJS 1.1.5. Пример больше не работает.
я узнал, что $httpProvider.responseInterceptors
устарела в 1.1.5. Вместо этого следует использовать $httpProvider.interceptors
К сожалению, просто замена вышеуказанной строки в Plunker не решила проблему. Кто-нибудь когда-нибудь делал такой загрузочный спиннер, используя HttpInterceptor в AngularJS 1.1.5?
Спасибо за вашу помощь!
Майкл
3 ответа
Благодаря подсказке Стива я смог реализовать загрузчик:
перехватчик:
.factory('httpInterceptor', function ($q, $rootScope, $log) {
var numLoadings = 0;
return {
request: function (config) {
numLoadings++;
// Show loader
$rootScope.$broadcast("loader_show");
return config || $q.when(config)
},
response: function (response) {
if ((--numLoadings) === 0) {
// Hide loader
$rootScope.$broadcast("loader_hide");
}
return response || $q.when(response);
},
responseError: function (response) {
if (!(--numLoadings)) {
// Hide loader
$rootScope.$broadcast("loader_hide");
}
return $q.reject(response);
}
};
})
.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
});
Директива:
.directive("loader", function ($rootScope) {
return function ($scope, element, attrs) {
$scope.$on("loader_show", function () {
return element.show();
});
return $scope.$on("loader_hide", function () {
return element.hide();
});
};
}
)
CSS:
#loaderDiv {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1100;
background-color: white;
opacity: .6;
}
.ajax-loader {
position: absolute;
left: 50%;
top: 50%;
margin-left: -32px; /* -1 * image width / 2 */
margin-top: -32px; /* -1 * image height / 2 */
display: block;
}
HTML:
<div id="loaderDiv" loader>
<img src="src/assets/img/ajax_loader.gif" class="ajax-loader"/>
</div>
"responseInterceptors" устарел. "Перехватчики" заменили его множеством улучшений в предварительной версии. Сверху головы, я не помню, какая версия. Документация по этому вопросу невелика, поэтому вам, вероятно, лучше всего изучить исходный код.
Суть изменений выглядит следующим образом:
$httpProvider.interceptors.push(function($q, $rootScope) {
return {
'request': function(config) {
// intercepts the request
},
'response': function(response) {
// intercepts the response. you can examine things like status codes
},
'responseError': function(response) {
// intercepts the response when the response was an error
}
}
});
В угловом источнике вы найдете документацию в разделе "* # Перехватчики" в функции $HttpProvider. Существует пример использования, очень похожий на тот, который я опубликовал выше.
Предоставленное / принятое решение отлично, если вы хотите включить JQuery в свое решение, которое команда AngularJS рекомендует не продвигать. element.show/.hide не поддерживается в JQLite Angular.... Поэтому для работы в сеансе не-jquery необходимы следующие рефакторы:
Измените элемент HTML, чтобы добавить класс "скрытый"
<div id="loaderDiv" loader class="hidden">
<img src="Content/images/yourgif.gif" class="ajax-loader" />
</div>
Добавьте скрытый класс к вашему CSS:
.hidden{display:none !important}
И подправить директиву так:
(function() {
'use strict';
angular
.module('your_app')
.directive('yourSpinner', yourSpinner);
yourSpinner.$inject = ['$rootScope'];
function yourSpinner($rootScope) {
return function($scope, element, attrs) {
$scope.$on("loader_show", function () {
if (element.hasClass("hidden")) {
element.removeClass("hidden")
}
});
return $scope.$on("loader_hide", function () {
if(!element.hasClass("hidden")){
element.addClass("hidden")
}
});
}
}
})();
Фабрика в порядке, как есть.