将 $http 注入 angular factory($exceptionHandler) 会导致循环依赖

Posted

技术标签:

【中文标题】将 $http 注入 angular factory($exceptionHandler) 会导致循环依赖【英文标题】:Injecting $http into angular factory($exceptionHandler) results in a Circular dependency 【发布时间】:2014-04-15 10:37:51 【问题描述】:

当我尝试将 $http 注入被覆盖的工厂时,我得到了错误:

未捕获的错误:[$injector:cdep] 找到循环依赖项:$http

AngularModule.factory('$exceptionHandler',  function ($http) 

任何想法如何解决?如果我使用 [] 注入,$http 是未定义的

edit__________________

根据我尝试过的以下答案:

MyModule.config(function($provide, $http) 
    $provide.decorator("$exceptionHandler", function($delegate) 
        return function(exception, cause) ..

但我仍然收到循环错误:

未捕获的错误:[$injector:cdep] 找到循环依赖项:$http

【问题讨论】:

我不知道你为什么将 $http 注入核心工厂?难怪你会得到一个循环 DI。也许创建一个自定义工厂,在其中注入 $exceptionHandler 和 $http ? @AlexC 默认情况下我只想使用 $http 记录服务器端.. .factory('My', function () ) .factory('$exceptionHandler', function ($log,My) ) 如果您在 My I get Error 上传递 $http 则有效: [$injector:cdep] errors. @FutuToad 将 $decorate 在这里是正确的,如果你想重载类似 $log 的功能? @c0bra 是的,你能检查我的编辑吗 【参考方案1】:

注入$injector,然后从那里获取$http 服务。像这样的:

AngularModule.factory('$exceptionHandler',  function ($injector) 
    var $http = $injector.get("$http");

见https://groups.google.com/forum/#!topic/angular/lbFY_14ZtnU/discussion

但是,这将完全覆盖 Angular 提供的 $exceptionHandler 功能。如果您只想将服务器端日志添加到现有功能,请参阅 this question 关于增强 $exceptionHandler 功能。

【讨论】:

不幸的是我也不能这样做:var $http = $injector.get("$http"); 我收到错误 $http 我不认为循环依赖来自 $injector。通过直接从 $injector 获取它们,我已经解决了许多循环依赖项。确保您仍然没有尝试在 $exceptionHandler 的任何地方连接 $http。 @FutuToad 我认为 dnc253 是对的。检查这个 plunker:plnkr.co/edit/0ilJj4?p=preview 另外,$q 有 finally,而不是 always 如果缩小代码,您必须像其他任何地方一样使用数组表示法。 (['$injector', function ($injector) ...) 对我来说var $http = $injector.get("$http"); 实际上没有用,它仍然过早地解决了依赖关系。一个简单但也不漂亮的替代方法是在实际逻辑中执行$injector.get("$http").get(....);【参考方案2】:

我正在使用这个解决方案,因为 rootScope 存在循环依赖问题:

angular
  .module('facilityLog')
  .provider('$exceptionHandler', function() 
 "use strict";

 this.$get = function($injector) 

  function exceptionHandler(exception, cause) 
   // This is the part where you get the instance of $http in your case
   var $rootScope = $injector.get('$rootScope');
   //...
  

  return exceptionHandler;

);

因此,如果您在 exceptionHandler-Function 中请求实例,您将不会收到循环依赖错误。

【讨论】:

【参考方案3】:

我使用以下方法解决了这个问题。请注意如何使用数组表示法使这种缩小安全。 另请注意,我完全覆盖了 $esceptionHandler 并使用我自己的服务来替换它。

angular
    .module('app')
    .factory('$exceptionHandler', $exceptionHandler);

$exceptionHandler.$inject = ['$injector', 'exceptionLoggingService'];

function $exceptionHandler($injector, exceptionLoggingService)

    return function(exception, cause)
    
        exceptionLoggingService.http = exceptionLoggingService.http || $injector.get('$http');
        exceptionLoggingService.error(exception, cause);
    ;

【讨论】:

以上是关于将 $http 注入 angular factory($exceptionHandler) 会导致循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

如何使用构造函数上的异步调用注入服务,Angular 2

AngularJS $在服务注入中注入错误

将 angularjs 服务注入 Angular

将 TranslateService 注入拦截器时的 Angular 循环依赖

Angular 2 将一个类注入到服务中

是否可以将服务注入 Angular 1.5 组件的 templateUrl 属性?