2014-02-28 170 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調用。代碼沒有經過測試,因爲它只是如何做到這一點的基本想法。你也應該小心,因爲這會造成無限循環。

希望這會有所幫助!