Правильный способ отключить / удалить http-перехватчики в Angular?

Я следил за этим сообщением, чтобы реализовать аналогичный образ загрузчика ajax в проекте:

моя реализация имеет несколько отличий:

  • я использую $rootScope до emit, а не broadcast и я также использовать $rootScope на директиве для обработки события.
  • из-за особенностей проекта я должен отменить директиву $rootScope.$on прослушиватели сразу после запуска первого события (для показа или скрытия) внутри обработчика событий.
  • я запускаю только одно событие show / hide. Показать на первом HTTP-запросе, скрыть, когда количество достигает 0.

Я считаю, что это основные отличия от связанного поста, не уверен, что они имеют отношение к моему вопросу, но на всякий случай...

когда загрузчик скрыть событие обрабатывается, загрузчик ушел, и я не буду показывать его снова если страница не обновлена, но у меня все еще есть фоновые http-запросы для обновления данных на текущей странице. Эти запросы по-прежнему будут перехватываться и запускать новые события show/hide, которые больше не требуются/обрабатываются. Мне нужно только первое шоу и первое укрытие, вот и все.

Как правильно удалить http-перехватчик, который я добавил в $httpProvider после того, как первое событие hide было запущено?

Я знаю, что мы добавляем перехватчик с помощью $httpProvider.interceptors.push() но Я не уверен, как его вытащить, когда мне больше не нужен этот перехватчик.

2 ответов


Я собирался назначить награду за это, так как у меня был тот же вопрос. Однако....он выглядит, как будто interceptors и responseInterceptors - это просто массивы, согласно исходный код (строки 127 и 133 в $httpProvider фабрика). Здесь нет обертки.

из того, что я могу сказать, вам либо придется использовать pop() или любой другой метод выбора. Однако это означает, что вы не знаете, что вы хлопаете! Хранит ссылку на объект не помочь, потому что на самом деле вы не можете выполнять функцию массива, если вы не решите итерацию на основе равенства (что может работать, используя indexOf или что-то еще вроде подчеркивания).

на самом деле, то, что угловой нуждается в оболочке для этого, так как вы не можете быть уверены, что ваш перехватчик является последним в списке.


лучшее решение, которое я нашел, - это то, которое объяснил Джедд.ahyoung в комментарии.

эти шаги.

добавить два пользовательских фабрики

angular.module('myModule.services', [])
/**
 * Save application information.
 */
.factory('Application', function($log) {
    return {};
})

/**
 * Custom Http Interceptor for the loader.
 */
.factory('myHttpInterceptor', function($rootScope, $q, Application) {
    return {
          request: function(config) {
            if(Application.enableLoader){
                $rootScope.$broadcast('loading:show');
            }
            return config;
          },

          requestError: function(rejection) {
              $rootScope.$broadcast('loading:hide');
              return $q.reject(rejection);
          },


          response: function(response) {
            $rootScope.$broadcast('loading:hide');
            return response;
          },

          responseError: function(rejection) {
              $rootScope.$broadcast('loading:hide');
              return $q.reject(rejection);
          }
    };
});

добавьте его в свой config шаг

.config(function($httpProvider) {
    //loading interceptor
    $httpProvider.interceptors.push('myHttpInterceptor');
});

включить/отключить его, когда/где вы хотите

Application.enableLoader = true;

$http({
  url: url,
  method: "GET"
}).success(function(data){
  $log.log("Data received and my loader is already closed :)");
  Application.enableLoader = false;
  $scope.retrieveBooks();
}).error(function(){
  $log.log("Error, but my loader is already closed :)");
  Application.enableLoader = false;
  $scope.retrieveBooks();
});


$scope.retrieveBooks = function(){
  $http({
    url: url,
    method: "GET"
  }).success(function(data){
    $log.log("Data received and my loader is not closed :(");
  }).error(function(){
    $log.log("Error, but my loader is not closed :(");
  });
};