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

问题描述

我在将依赖项注入拦截器时遇到问题。我想将 TranslateService 注入 HttpErrorInterceptor,但出现循环依赖错误。当我删除 TranslateService 注入时,一切正常。

我在 app.module.ts 中声明了拦截器。 我的应用模块如下所示:

@NgModule({
 declarations: [
   AppComponent
 ],imports: [
   browserModule,browserAnimationsModule,CoreModule,HttpClientModule,TranslateModule.forRoot({
   loader: {
      provide: TranslateLoader,useFactory: HttpLoaderFactory,deps: [HttpClient],},defaultLanguage: 'pl-pl'
 }),AppRoutingModule,RouterModule,FormsModule,ReactiveFormsModule,ToastrModule.forRoot()
 ],providers: [
   {
     provide: HTTP_INTERCEPTORS,useClass: JwtInterceptor,multi: true
   },{
     provide: HTTP_INTERCEPTORS,useClass: HttpErrorInterceptor,multi: true,deps: [TranslateService,ToastrService]
   }
 ],bootstrap: [AppComponent]
})
export class AppModule { }

在 AppModule 中,我导入了 CoreModule,其中有一个包含拦截器的文件夹,我的 CoreModule 如下所示:

@NgModule({
  declarations: [],imports: [
    CommonModule
  ],providers: [
    CookieService,NoAuthGuard,AuthGuard
  ]
})
export class CoreModule { }

我把登录页面放在 AuthModule 中,如下所示:

@NgModule({
  declarations: [LoginComponent,AuthComponent,ForgotPasswordComponent],imports: [
    CommonModule,AuthRoutingModule,SharedModule
  ],providers: [
    AuthService
  ]
})
export class AuthModule { }

在 Authmodule 中,我导入了 SharedModule,其中我导出了 TranslateModule。 而 SharedModule 看起来像这样:

@NgModule({
  declarations: [],ReactiveFormsModule
  ],exports: [
    TranslateModule,ReactiveFormsModule
  ]
})
export class SharedModule { }

我不知道为什么我在登录页面上出现循环依赖错误

我的假设是我已经将 CoreModule 导入到 AppModule 中,在那里我保留了拦截器、守卫和 SharedModule,它对所有功能模块进行了即兴发挥,我想保留例如那里有通用组件。

Błąd,jaki dostaję 到:

core.js:6162 ERROR Error: NG0200: Circular dependency in DI detected for InjectionToken HTTP_INTERCEPTORS. Find more at https://angular.io/errors/NG0200
    at throwCyclicDependencyError (core.js:216)
    at R3Injector.hydrate (core.js:11381)
    at R3Injector.get (core.js:11205)
    at HttpInterceptingHandler.handle (http.js:1978)
    at MergeMapSubscriber.project (http.js:1114)
    at MergeMapSubscriber._tryNext (mergeMap.js:44)
    at MergeMapSubscriber._next (mergeMap.js:34)
    at MergeMapSubscriber.next (Subscriber.js:49)
    at Observable._subscribe (subscribetoArray.js:3)
    at Observable._trySubscribe (Observable.js:42)

请帮忙。

解决方法

您遇到的问题是,对于 TranslateModule 的初始化,您依赖于 HttpClient,这意味着需要先初始化 HttpClientModule。这会导致您的 HttpErrorInterceptor 初始化,因为拦截器是使用 HttpClientModule 初始化进行初始化的。这会导致循环依赖,因为您的拦截器需要 TranslateService。您可以通过在 HttpErrorInterceptor 中注入 Injector 来解决此问题,然后在需要时直接从注入器按需请求 TranslateService。这样可以防止对初始初始化的循环依赖。

由于您没有为拦截器提供代码,这里提供了一个使用这种方法的拦截器示例。

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
  constructor(private readonly injector: Injector) {}

  public intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
    try {
      const translateService = this.injector.get(TranslateService)
      // log using translate service
    } catch {
      // log without translation translation service is not yet available
    }
  }
}

您仍然需要处理获取翻译服务失败的情况,因为您可能会在加载翻译时出错。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...