12

我按照这篇文章在一个项目上实现了一个类似的 ajax 加载器图像:

我的实现有一些不同之处:

  • 我使用$rootScopetoemit和 not broadcast,我也使用$rootScopeon 指令来处理事件。
  • 由于项目的特殊性,我必须$rootScope.$on在事件处理程序内的第一个事件被触发(显示或隐藏)之后立即取消绑定指令侦听器。
  • 我只触发一个显示/隐藏事件。在第一个 HTTP 请求时显示,当计数达到 0 时隐藏。

我相信这些是与链接帖子的主要区别,不确定它们是否与我的问题相关,但以防万一他们......

加载器隐藏事件处理后,加载器消失了,除非刷新页面,否则我不会再次显示它,但我仍然有后台http请求刷新当前页面上的数据。这些请求仍将被拦截并触发不再需要/处理的新显示/隐藏事件。我只需要第一次表演和第一次隐藏,就是这样。

$httpProvider在触发第一个隐藏事件后,删除我添加到的 HTTP 拦截器的正确方法是什么?

我知道我们使用 a 添加拦截器,$httpProvider.interceptors.push()但是当我不再需要该拦截器时,我不确定如何将其弹出。

4

2 回答 2

3

我打算为此悬赏,因为我有同样的问题。但是....根据源代码(工厂中的第 127 和 133 行),看起来interceptorsandresponseInterceptors只是数组。这没有包装。$httpProvider

据我所知,您要么必须使用,要么必须使用pop()任何其他数组方法。然而,这意味着你不知道你在弹出什么!持有对对象的引用并没有真正的帮助,因为你不能真正对它执行数组函数,除非你决定基于相等进行迭代(这可以工作,使用 indexOf 或其他类似下划线的东西)。

真的,Angular 需要的是一个包装器,因为你不能确定你的拦截器是列表中的最后一个。

于 2014-02-21T04:19:37.480 回答
1

我发现的最佳解决方案是 jedd.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 :(");
  });
};
于 2015-06-19T13:31:33.107 回答