luk*_*ear 8 cyclic-dependency ngx-translate angular
我在将依赖项注入拦截器时遇到问题。我想将 TranslateService 注入 HttpErrorInterceptor,但出现循环依赖错误。当我删除 TranslateService 注入时,一切正常。
\n我已在 app.module.ts 中声明了拦截器。\n我的应用程序模块如下所示:
\n@NgModule({\n declarations: [\n AppComponent\n ],\n imports: [\n BrowserModule,\n BrowserAnimationsModule,\n CoreModule,\n HttpClientModule,\n TranslateModule.forRoot({\n loader: {\n provide: TranslateLoader,\n useFactory: HttpLoaderFactory,\n deps: [HttpClient],\n },\n defaultLanguage: \'pl-pl\'\n }),\n AppRoutingModule,\n RouterModule,\n FormsModule,\n ReactiveFormsModule,\n ToastrModule.forRoot()\n ],\n providers: [\n {\n provide: HTTP_INTERCEPTORS,\n useClass: JwtInterceptor,\n multi: true\n },\n {\n provide: HTTP_INTERCEPTORS,\n useClass: HttpErrorInterceptor,\n multi: true,\n deps: [TranslateService, ToastrService]\n }\n ],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\nRun Code Online (Sandbox Code Playgroud)\n在 AppModule 中,我导入了 CoreModule,其中有一个包含拦截器的文件夹,我的 CoreModule 如下所示:
\n@NgModule({\n declarations: [],\n imports: [\n CommonModule\n ],\n providers: [\n CookieService,\n NoAuthGuard,\n AuthGuard\n ]\n})\nexport class CoreModule { }\n\nRun Code Online (Sandbox Code Playgroud)\n我将登录页面放在AuthModule中,如下所示:
\n@NgModule({\n declarations: [LoginComponent, AuthComponent, ForgotPasswordComponent],\n imports: [\n CommonModule,\n AuthRoutingModule,\n RouterModule,\n SharedModule\n ],\n providers: [\n AuthService\n ]\n})\nexport class AuthModule { }\nRun Code Online (Sandbox Code Playgroud)\n在 Authmodule 中,我导入了 SharedModule,其中导出了 TranslateModule。\nSharedModule 如下所示:
\n@NgModule({\n declarations: [],\n imports: [\n CommonModule,\n HttpClientModule,\n ReactiveFormsModule\n ],\n exports: [\n TranslateModule,\n ReactiveFormsModule\n ]\n})\nexport class SharedModule { }\nRun Code Online (Sandbox Code Playgroud)\n我无法找出为什么登录页面上出现循环依赖错误。
\n我的假设是,我已将 CoreModule 导入到 AppModule 中,在其中保留拦截器、防护程序,并且我有 SharedModule,它为所有功能模块提供临时功能,并且我想在那里保留例如通用组件。
\nB\xc5\x82\xc4\x85d,jaki dostaj\xc4\x99 到:
\ncore.js:6162 ERROR Error: NG0200: Circular dependency in DI detected for InjectionToken HTTP_INTERCEPTORS. Find more at https://angular.io/errors/NG0200\n at throwCyclicDependencyError (core.js:216)\n at R3Injector.hydrate (core.js:11381)\n at R3Injector.get (core.js:11205)\n at HttpInterceptingHandler.handle (http.js:1978)\n at MergeMapSubscriber.project (http.js:1114)\n at MergeMapSubscriber._tryNext (mergeMap.js:44)\n at MergeMapSubscriber._next (mergeMap.js:34)\n at MergeMapSubscriber.next (Subscriber.js:49)\n at Observable._subscribe (subscribeToArray.js:3)\n at Observable._trySubscribe (Observable.js:42)\nRun Code Online (Sandbox Code Playgroud)\n
Ale*_*esD 14
您遇到的问题是,对于您的初始化,您TranslateModule依赖于这HttpClient意味着HttpClientModule需要首先初始化。这会导致您的初始化,HttpErrorInterceptor因为拦截器是通过HttpClientModule初始化来初始化的。这会导致循环依赖,因为您的拦截器需要TranslateService. 您可以通过将注入器注入到您的注入器中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
}
}
}
Run Code Online (Sandbox Code Playgroud)
您仍然需要处理获取翻译服务失败的情况,因为加载翻译时可能会出现错误。
Aar*_*lal 11
根据这个GitHub 问题,一些人(包括我自己)能够通过删除defaultLanguagein来解决这个问题TranslateModule.forRoot()
我已经实现了我的 LanguageModule 如下:
@NgModule({
imports: [
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
},
isolate: true
})
],
providers: [
TranslateService
]
})
export class LanguageModule {
public constructor(translateSvc: TranslateService, http: HttpClient) {
translateSvc.onLangChange
.pipe(
switchMap((currentLang: LangChangeEvent) => zip(
of(currentLang),
http.get(`path/to/i18n/${currentLang.lang}.json`)
))
).subscribe(([currentLang, localizations]) => {
translateSvc.setTranslation(translateSvc.currentLang, localizations, true);
});
translateSvc.use(translateSvc.getDefaultLang());
}
Run Code Online (Sandbox Code Playgroud)
然后将其导入到我的CoreModule:
@NgModule({
imports: [
CommonModule,
HttpClientModule,
BrowserAnimationsModule,
LanguageModule,
...
],
exports: [],
declarations: [],
providers: [
...
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class CoreModule {
public constructor(@Optional() @SkipSelf() parentModule: CoreModule, private translateSvc: TranslateService) {
this.translateSvc.use(environment.defaultLang)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12160 次 |
| 最近记录: |