2014-02-28 120 views
2

所以我拦截了一个角度$ http请求和响应。可以说,如果我有一个响应错误,我想重新激活我的$ http调用。问题是我需要在我的拦截器中注入$ http服务,并创建一个循环依赖。这是我的代码中的CoffeeScript简化版本:

retryModule = angular.module('retry-call', []) 

retryModule.factory 'RetryCall', ($q, $http)-> 
    # More object keys 
    'responseError': (response)=> 
    # Retry request if failed 
    # I need a different way of invoking $http() to avoid circular dependency 
    $http(response.config) 
    $q.reject(response) 

retryModule.config ['$httpProvider', ($httpProvider)-> 
    $httpProvider.interceptors.push('RetryCall'); 
] 

感谢

+1

检查这个答案:http://stackoverflow.com/questions/21119016/is-there-a-way-to-request-http-for-an-interceptor/21119959#21119959 –

+0

我希望我想到这一点。现在我感到哑巴,哈哈。 –

回答

0

在回顾了Angular源代码后,更好的答案就是这样。 $ http方法可以在不依赖注入的情况下访问,所以技巧是不注入$ http并简单地使用它。喜欢这样:

Right Way 

retryModule = angular.module('retry-call', []) 

# Do not inject $http 
retryModule.factory 'RetryCall', ($q)-> 
    # More object keys 
    'responseError': (response)=> 
    # Just use $http without injecting it 
    $http(response.config) 
    $q.reject(response) 

retryModule.config ['$httpProvider', ($httpProvider)-> 
    $httpProvider.interceptors.push('RetryCall'); 
] 

Wrong Way 

# Do not do it this way. 
retryModule.factory 'RetryCall', ($q,$http)-> 
1

为了避免循环依赖,你可以永远只是装点$http服务来处理此功能。这是一个装饰者的example

你基本上会做这样的事伪代码:

var old_post = $delegate.post; 
$delegate.post = function(post_stuff) { 
    var def = $q.defer(); 
    old_post(post_stuff).then(function(data) { 
     if (data.error) { 
      $delegate.post(post_stuff).then(function(data) { 
       def.resolve(data); 
      } 
     } else { 
      def.resolve(data) 
     } 
    }, function(err_data) { 
     // Also retry here 
    }); 
}; 
return $delegate; 

这基本上包在重试功能,原来的$ HTTP调用。代码没有经过测试,因为它只是如何做到这一点的基本想法。你也应该小心,因为这会造成无限循环。

希望这会有所帮助!