代码之家  ›  专栏  ›  技术社区  ›  Rotem jackoby

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

  •  20
  • Rotem jackoby  · 技术社区  · 6 年前

    我正在尝试通过新的 providedIn 属性。

    这是我在受保护模块中使用的翻译冲突解决程序:

    import { Injectable } from '@angular/core';
    
    import { Observable , pipe } from 'rxjs';
    import {map} from "rxjs/operators";
    
    //This is causing: "WARNING in Circular dependency detected:"
    import {ProtectedModule} from "../../../protected/protected.module";
    
    import { HttpHandlerService } from '../../http/http-handler.service';
    
    @Injectable({
      providedIn: ProtectedModule //Over here (I need the import for this line)
    })
    export class TranslationsResolverService {
      constructor(private _httpHandlerService : HttpHandlerService) { }
        resolve(): any {
          //Do Something...
        }
    }

    我在受保护的路由模块中声明了翻译解析程序服务:

    import { NgModule }           from '@angular/core';
    import {RouterModule, Routes} from '@angular/router';
    
    import {AuthGuard} from "../core/resolvers/auth/auth.guard";
    import {TranslationsResolverService} from "./../core/resolvers/translations/translations-resolver.service";
    
    const routes: Routes = [
      {
        path : 'app' ,
        component: ProtectedComponent,
        resolve : {
          translations : TranslationsResolverService // <---- Over here - i can't remove that of course
        },
        canActivate: [AuthGuard],
        ]
      }
    ];
    
    
    @NgModule({
      imports : [RouterModule.forChild(routes)],
      exports : [RouterModule]
    })
    export class ProtectedRoutingModule { }

    因为我导入(typescript导入)的事实 protected.module translations-resolver.service.ts 为了在 普罗维登丁 属性 我在检测到循环依赖项时收到警告:

    path/to/translations-resolver.service.ts -> 
    
    protected/protected.module.ts ->
    
    protected/protected-routing.module.ts -> 
    
    path to translations-resolver.service.ts
    

    第二个路径(protected/protected.module.ts)是由于 普罗维登丁 属性。

    我可以通过提供 translationsResolver 作为一个 NgModule provider (在providers数组中)但我希望它是 injectable 供应商。

    有什么解决这个问题的建议吗?

    4 回复  |  直到 5 年前
        1
  •  7
  •   Reactgular    6 年前

    这不是角度依赖性问题。

    循环引用是由typescript编译器在尝试解析循环时生成的。 进口 .

    第一个解决方案

    创建名为的新模块 ProtectedResolversModule 和使用 providedIn: ProtectedResolversModule 把分解器移到那里。

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

    第二个解决方案

    使用 providers 数组 保护模块 .

        2
  •  10
  •   DarkNeuron    6 年前

    我也遇到了同样的问题。结果发现,解决办法是“不要这样做”,正如一个有棱角的家伙在这条线中所解释的: https://github.com/angular/angular-cli/issues/10170#issuecomment-380673276

    归根结底,当根模块提供服务时,可以更容易地对它们进行树型抖动。

    我和你一样失望。

        3
  •  2
  •   Dan King    5 年前

    我觉得角型的有点乱 providedIn 语法。这似乎让很多人困惑。例如,请参见以下两个Github线程:

    这个 普罗维登丁 语法似乎有两个主 利益 以下内容:

    1. 它支持未使用服务的树摇晃
    2. providedIn: 'root' 确保您只获得服务的一个实例

    但你只需要(1)如果你在写 图书馆 而不是 应用 (因为为什么要在应用程序中包含不需要的服务),并且只需确保不多次导入服务模块,就可以避免多个服务实例(2)。

    这个 问题 普罗维登丁 语法是:

    1. providedIn:'根' 中断服务和它“所在”的模块(或“与”)之间的链接-因为服务不了解模块,模块不知道服务。这意味着该服务不再真正“属于”该模块,而将与它的任何引用捆绑在一起。这就意味着现在由服务决定了 消费者 为了确保服务的可注入依赖项(如果有)在使用之前是可用的,这是令人困惑的,而且非常违反直觉。
    2. 上面描述的循环参考问题。实际上不是 可能的 -通过此语法-为了保留服务与其模块之间的链接, 如果同一模块中的任何组件实际使用该服务 .

    这与官方的角度指导相反,但我的建议是: 不使用 普罗维登丁 ,除非您正在编写第三方库,该库需要树震动 -使用旧的(不推荐使用) providers 模块上的语法,即:

    @NgModule({ providers: [MyService], })

        4
  •  0
  •   Ozgur    6 年前

    检查 forwardRef() 角度/核心功能。它允许引用尚未定义的引用。

    import {MyService} from './service';
    
    constructor(@Inject(forwardRef(() => MyService)) public myService: MyService) {
    }
    
    推荐文章