Angular (4): 自定义错误处理程序和 DI: 无法实例化循环依赖
Angular (4): Custom Error Handler & DI: Cannot instantiate cyclic dependency
我正在尝试将 Angular Material 2 元素注入到我编写的自定义错误处理程序中,但我不断收到此错误:
Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
这是错误处理程序 class:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private snackBar: MdSnackBar) {
}
handleError(error: any): void {
//FIXME: display popup
console.error('Error occurred!');
console.error(error);
this.snackBar.open('Application Error: ' + error, 'X', {
duration: environment.snackBarTime,
});
}
}
这是 app.module
的提供商部分
providers: [
SearchService,
CompanyService,
MdSnackBar,
PopupService,
AuthService,
LoginService,
AuthGuard,
ErrorService,
TokenStorageService,
BankService,
CountryService,
{provide: ErrorHandler, useClass: CustomErrorHandler},
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
],
exports: [
TranslateModule
],
bootstrap: [AppComponent]
})
在handleError函数的执行过程中,我们必须手动调用带有服务名称的注入器。
所以我不得不使用内置的 Inject
来注入我的服务依赖。 custom-error-handler
class 调用具有 MdSnackBar
依赖项注入的 PopupService
的最终结果如下所示:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private injector: Injector) {
}
handleError(error: any): void {
console.log(error);
const popupService = this.injector.get(PopupService);
}
}
这是 PopupService:
@Injectable()
export class PopupService {
constructor(private snackBar: MdSnackBar) {
}
public throwErrorPopup(textOfError: string) {
this.snackBar.open(textOfError, 'X', {
duration: environment.snackBarTime,
});
}
}
这里提到的解决方案:https://medium.com/@amcdnl/global-error-handling-with-angular2-6b992bdfb59c
在我的例子中,问题是我将服务注入到它自己的构造函数中。我在复制代码时犯了这个菜鸟错误。如果对像我这样的人有帮助的话。
export class AskLanguageProvider {
public selectedLang = new Subject<any>();
constructor(private alertCtrl: AlertController,
public storage: Storage,
private lan: AskLanguageProvider, // <= The culprit
public translate: TranslateService) { }
接受的答案对我不起作用,对我来说似乎没有提供者错误。但我发现了不同的方法来实现这一目标。
我从 app.module.ts 构造函数调用 WampService setter 方法,该方法需要包含 WampErrorHandler 服务。
export class AppModule {
constructor(private wampService: WampService) {
this.wampService.setErrorHandler(WampErrorHandler);
}
}
但是在 WampService 中的 setErrorHandler 方法看起来像这样:
setErrorHandler(handler) {
this.wampErrorHandler = this.injector.get(handler)
};
我也在构造函数中使用 Injector:
constructor(private injector: Injector) {}
我正在尝试将 Angular Material 2 元素注入到我编写的自定义错误处理程序中,但我不断收到此错误:
Cannot instantiate cyclic dependency! ApplicationRef ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
这是错误处理程序 class:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private snackBar: MdSnackBar) {
}
handleError(error: any): void {
//FIXME: display popup
console.error('Error occurred!');
console.error(error);
this.snackBar.open('Application Error: ' + error, 'X', {
duration: environment.snackBarTime,
});
}
}
这是 app.module
的提供商部分providers: [
SearchService,
CompanyService,
MdSnackBar,
PopupService,
AuthService,
LoginService,
AuthGuard,
ErrorService,
TokenStorageService,
BankService,
CountryService,
{provide: ErrorHandler, useClass: CustomErrorHandler},
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
],
exports: [
TranslateModule
],
bootstrap: [AppComponent]
})
在handleError函数的执行过程中,我们必须手动调用带有服务名称的注入器。
所以我不得不使用内置的 Inject
来注入我的服务依赖。 custom-error-handler
class 调用具有 MdSnackBar
依赖项注入的 PopupService
的最终结果如下所示:
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private injector: Injector) {
}
handleError(error: any): void {
console.log(error);
const popupService = this.injector.get(PopupService);
}
}
这是 PopupService:
@Injectable()
export class PopupService {
constructor(private snackBar: MdSnackBar) {
}
public throwErrorPopup(textOfError: string) {
this.snackBar.open(textOfError, 'X', {
duration: environment.snackBarTime,
});
}
}
这里提到的解决方案:https://medium.com/@amcdnl/global-error-handling-with-angular2-6b992bdfb59c
在我的例子中,问题是我将服务注入到它自己的构造函数中。我在复制代码时犯了这个菜鸟错误。如果对像我这样的人有帮助的话。
export class AskLanguageProvider {
public selectedLang = new Subject<any>();
constructor(private alertCtrl: AlertController,
public storage: Storage,
private lan: AskLanguageProvider, // <= The culprit
public translate: TranslateService) { }
接受的答案对我不起作用,对我来说似乎没有提供者错误。但我发现了不同的方法来实现这一目标。
我从 app.module.ts 构造函数调用 WampService setter 方法,该方法需要包含 WampErrorHandler 服务。
export class AppModule {
constructor(private wampService: WampService) {
this.wampService.setErrorHandler(WampErrorHandler);
}
}
但是在 WampService 中的 setErrorHandler 方法看起来像这样:
setErrorHandler(handler) {
this.wampErrorHandler = this.injector.get(handler)
};
我也在构造函数中使用 Injector:
constructor(private injector: Injector) {}