Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度6+;:在非根模块中提供导致循环依赖_Angular_Typescript_Angular6_Angular7 - Fatal编程技术网

Angular 角度6+;:在非根模块中提供导致循环依赖

Angular 角度6+;:在非根模块中提供导致循环依赖,angular,typescript,angular6,angular7,Angular,Typescript,Angular6,Angular7,我正在尝试通过新的providedIn属性提供解析服务 这是我在受保护模块中使用的翻译解析器: 从'@angular/core'导入{Injectable}; 从“rxjs”导入{observatable,pipe}; 从“rxjs/operators”导入{map}; //这导致:“检测到循环依赖项中的警告:” 从“../../../protected/protected.module”导入{ProtectedModule}; 从“../../http/http handler.servic

我正在尝试通过新的
providedIn
属性提供解析服务

这是我在受保护模块中使用的翻译解析器:

从'@angular/core'导入{Injectable};
从“rxjs”导入{observatable,pipe};
从“rxjs/operators”导入{map};
//这导致:“检测到循环依赖项中的警告:”
从“../../../protected/protected.module”导入{ProtectedModule};
从“../../http/http handler.service”导入{HttpHandlerService};
@注射的({
providedIn:ProtectedModule//在这里(我需要这一行的导入)
})
导出类TranslationsResolversService{
构造函数(私有httpHandlerService:httpHandlerService){}
resolve():任何{
//做点什么。。。
}
}
从角度/核心检查功能。它允许引用尚未定义的引用

从“/service”导入{MyService};
构造函数(@Inject(forwardRef(()=>MyService))公共MyService:MyService){
}

我遇到了同样的问题。事实证明,解决方案是“不要这样做”,正如其中一个有棱角的家伙在这篇文章中所解释的:

据我所知,归根结底,当服务由根模块提供时,它们更容易树抖动


我和你一样失望。

这不是角度相关性问题

当TypeScript编译器尝试解析循环导入时,循环引用由它生成

第一种解决方案 创建一个名为
ProtectedResolversModule
的新模块,并使用在:ProtectedResolversModule中提供的
将解析程序移动到该模块

现在,您可以将该模块导入到
ProtectedModule
中,并且在加载
ProtectedRoutingModule
时不会出现循环依赖项错误

第二种解决方案 使用
ProtectedModule
providers
数组

更新日期:2019年10月 我已经收到了5张赞成票,所以我觉得我应该坦率地说,我不再真正遵循我自己的建议(见下文)

由于官方的(并且被广泛采用的)Angular策略是使用“root”中提供的
,因此我决定,总体而言,如果我坚持这样做,其他开发人员就不会那么困惑了。到目前为止,它还没有给我带来任何问题,但下面的警告仍然存在,我相信保持对这一点的意识是很重要的

原职 我认为Angular把
语法中提供的
弄得有点乱。这似乎让很多人感到困惑。例如,请参见以下两个github线程:

语法中提供的
似乎有两个主要好处:

  • 它支持未使用服务的树抖动
  • providedIn:'root'
    确保您只能获得一个服务实例
  • 但是,如果您正在编写库而不是应用程序,那么您只需要(1)(因为为什么要在应用程序中包含不需要的服务),并且您可以通过确保不多次导入服务模块来避免多个服务实例(2)

    语法中提供的
    问题有:

  • providedIn:'root'
    中断服务与它“所在”(或“使用”)的模块之间的链接-因为服务不知道模块,模块也不知道服务。这意味着该服务不再真正“属于”该模块,只会与引用它的任何内容捆绑在一起。这反过来意味着,现在由服务使用者来确保服务的可注入依赖项(如果有)在使用之前可用,这会让人感到困惑,而且非常不直观(当然,除非依赖项以及它们的依赖项等也都在“root”中提供,在这种情况下,它们会自行处理)
  • 上面描述的循环引用问题。如果同一模块中的任何组件实际使用服务,则实际上不可能通过此语法保留服务与其模块之间的链接
  • 这与官方角度指南相反,但我的建议是:不要使用
    中提供的
    ,除非您正在编写需要摇树的第三方库
    ——在模块上使用旧的(未弃用的)
    提供程序
    语法,即:

    @NgModule({providers:[MyService],})
    在Angular9中+

    您可以使用providerIn:任何

    基本上它的工作原理与模块类似,但您不直接使用模块,因此不再存在循环依赖关系

    文件:

    “any”:在每个延迟加载的模块中提供一个唯一的实例,而所有急切加载的模块共享一个实例

    换句话说,它位于不同的注入树中。它与您在其他模块中使用的实例不同

    更多裁判

    “Any”非常有助于确保服务是模块边界内的单例服务。它是“root”的一个可靠替代方案,以确保各个模块之间不会产生副作用

    providerIn的代码

      private injectableDefInScope(def: ɵɵInjectableDef<any>): boolean {
        if (!def.providedIn) {
          return false;
        } else if (typeof def.providedIn === 'string') {
          return def.providedIn === 'any' || (def.providedIn === this.scope);
        } else {
          return this.injectorDefTypes.has(def.providedIn);
        }
      }
    
    private-injectableDefInScope(def:ɵɵInjectableDef):布尔值{
    如果(!def.providedIn){
    返回false;
    }else if(typeof def.providedIn=='string'){
    返回def.providedIn=='any'| |(def.providedIn===this.scope);
    }否则{
    返回此.injectorDefTypes.has(def.providedIn);
    }
    }
    
    Ozgur我不确定这对解决循环依赖性有何帮助。与其在路由中注入服务,不如使用构造函数。在解析阶段,我必须在路由中“注入”(注册更正确)解析程序。我还想使用providedIn语法来标记解析程序的范围