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

2024-01-06

我在将依赖项注入拦截器时遇到问题。我想将 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,
    RouterModule,
    SharedModule
  ],
  providers: [
    AuthService
  ]
})
export class AuthModule { }

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

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    HttpClientModule,
    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。您可以通过注入来解决这个问题Injector https://angular.io/api/core/Injector在你的HttpErrorInterceptor然后请求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
    }
  }
}

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 TranslateService 注入拦截器时的 Angular 循环依赖 的相关文章

随机推荐