Angular2在自定义ErrorHandler中注入服务

时间:2017-01-11 08:22:49

标签: angular error-handling

我有以下代码:

app.module.ts:

NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        RouterModule,
        BrowserModule,
        ReactiveFormsModule,
        FormsModule,
        HttpModule,
        AppRoutingModule // Routes
    ],
    providers: [ // services
        AppLog,
        {provide: ErrorHandler, useClass: MyErrorHandler}
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

MyErrorHandler.ts:

@Injectable()
export class MyErrorHandler implements ErrorHandler {
  constructor (private _appLog: AppLog) {}

  handleError(error:any):void {
    let errorMessage: string = "" + error
    this._appLog.logMessageAsJson(errorMessage, "error")
            .subscribe(
              ...
            )
  }
}

appLog.ts

@Injectable()
export class AppLog {
    constructor (private _http: Http) {}

    logMessageAsJson(message: string, type: string) {
        let headers = new Headers({ "Content-Type": "application/json" })
        let jsonMessage = {"type": type, "message": message}

        return this._http.post(JSON.stringify(jsonMessage), headers)
    }
}

然而,当我的应用程序引导时,如果我在MyErrorHandler中注入了以下错误,则会失败:

Unhandled Promise rejection: Provider parse errors:
Cannot instantiate cyclic dependency!

如果我删除了constructor (private _appLog: AppLog) {},然后在handleError中执行其他操作,那么就可以正常工作并调用ErrorHandler。

我想它不起作用,因为AppLog和MyErrorHandler同时被实例化

2 个答案:

答案 0 :(得分:10)

您可以使用此解决方法来分解与DI

的循环依赖关系
@Injectable()
export class MyErrorHandler implements ErrorHandler {
  private _appLog: AppLog;
  constructor (injector:Injector) {
    setTimeout(() => this._appLog = injector.get(AppLog));
  }
  ...
}

Angulars DI本身并不支持循环依赖。

答案 1 :(得分:0)

ErrorHandler在提供程序之前创建。因此,我们需要在自定义错误处理程序类中使用Injector进行依赖项注入。

 Sub Test()
  Dim obj As Object
Set obj = YahooHigh("GOOG")

MsgBox obj("Time Series (Daily)")("2019-07-18")("2. high")
MsgBox obj("Time Series (Daily)")("2019-07-18")("4. close")

End Sub

通过Angular cli创建默认服务,然后检查第一部分,请参见@Injectable() export class MyErrorHandler implements ErrorHandler{ constructor(private injector: Injector) { } handleError(error: any) { let router = this.injector.get(ServiceName); } }

providedIn: 'root',

For more detail check angular @Injectable-level configuration

  

@NgModule级注射器   您可以使用非根NgModule的providers metadata选项在模块级别配置提供程序,以将提供程序的范围限制为该模块。这等效于在@Injectable()元数据中指定非根模块,除了通过提供者提供的服务不可摇树。