Javascript 循环依赖项,在验证ExceptionHandler时
我有以下代码:Javascript 循环依赖项,在验证ExceptionHandler时,javascript,angularjs,dependency-injection,typescript,angular,Javascript,Angularjs,Dependency Injection,Typescript,Angular,我有以下代码: import {Injectable, ExceptionHandler, SkipSelf, Host, Optional} from '@angular/core'; import {ToastNotification} from '../toast-messages/toastNotification.service'; export class UIError extends Error { constructor (private toastMessa
import {Injectable, ExceptionHandler, SkipSelf, Host, Optional} from '@angular/core';
import {ToastNotification} from '../toast-messages/toastNotification.service';
export class UIError extends Error {
constructor (private toastMessage: string) {
super();
this.toastMessage = toastMessage;
}
}
export class MyUIError extends UIError {}
export class AnotherError extends UIError {}
export class _ArrayLogger {
res = [];
log(s: any): void { this.res.push(s); }
logError(s: any): void { this.res.push(s); }
logGroup(s: any): void { this.res.push(s); }
logGroupEnd() {};
}
export class ConsoleLogger {
log(s: any): void {console.log(s);}
}
@Injectable()
export class CustomExceptionHandler extends ExceptionHandler {
constructor(private logger: ConsoleLogger, private toast: ToastNotification) {
super (new _ArrayLogger(), true);
}
call(exception: any, stackTrace = null, reason = null) {
let self = this;
if (exception.originalException instanceof UIError) {
self.toast.Error(exception.originalException.toastMessage);
} else {
this.logger.log(exception);
}
}
}
当我尝试运行这个程序时,我遇到了toast:toast通知的问题。我得到的错误是:
zone.js:260Uncaught EXCEPTION: Error during instantiation of ApplicationRef_! (ApplicationRef -> ApplicationRef_).
ORIGINAL EXCEPTION: Cannot instantiate cyclic dependency! (ExceptionHandler -> ToastNotification)
ORIGINAL STACKTRACE:
Error: DI Exception
at CyclicDependencyError.BaseException
我也将这个组件注入boostrap。如何解决这个问题?看到这个问题后,我认为这可能是解决您问题的方法。如果您控制循环依赖的一个类,则只需将
注入器
注入构造函数,然后获取实际需要的实例:
constructor(injector:Injector) {
setTimeout(() => this.someService = injector.get(SomeService));
}
在构造函数中使用注入器时,我仍然存在相同的问题。解决这个问题的方法是将注入部分移动到调用函数
@Injectable()
export class AppExceptionHandler extends ExceptionHandler {
private router:Router;
private toaster:ToastsManager;
constructor(private injector: Injector) {
super(new _ArrayLogger(), true);
}
call(exception:any, stackTrace?:any, reason?:string):void {
this.getDependencies();
console.log(exception);
if(exception.status === 401){
// Show login
this.router.navigate(['/login']);
}
// Get error messages if http exception
let msgs = [];
if(exception instanceof Response){
msgs = this.getMessagesFromResponse(exception);
}else{
// Otherwise show generic error
msgs.push('Something went wrong');
}
// Show messages
msgs.forEach((msg) => this.toaster.error(msg));
super.call(exception, stackTrace, reason);
}
private getDependencies(){
if(!this.router){
this.router = this.injector.get(Router);
}
if(!this.toaster){
this.toaster = this.injector.get(ToastsManager);
}
}
}
这是否意味着
ToastNotification
作为ExceptionHandler
作为构造函数参数?是的,它引用了一个AppRef,在它的树中有一些ExceptionHandler组件:(处理此问题的最佳方法是什么?我想不将ExceptionHandler
注入ToastNotification
DI无法处理循环依赖关系。这在技术上不可能用于构造函数注入。您可以在Angular之外创建实例并解决循环依赖关系im操作上,只使用ToastNotification
上的属性,其中ExceptionHandler
在实例化后分配,然后使用provide(…,{useValue:…})
提供所有相关实例,但这非常难看。另请参阅