簡體   English   中英

Angular2在自定義ErrorHandler中注入服務

[英]Angular2 Injecting services in custom ErrorHandler

我有以下代碼:

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)
    }
}

但是,當我的app bootstrap時,如果我在MyErrorHandler注入了以下錯誤,則會失敗:

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

如果我刪除constructor (private _appLog: AppLog) {}然后在handleError執行其他操作, handleError可以正常工作並調用ErrorHandler。

我想這不起作用,因為AppLog和MyErrorHandler同時被實例化

您可以使用此變通方法來分解與DI的循環依賴關系

@Injectable()
export class MyErrorHandler implements ErrorHandler {
  private _appLog: AppLog;
  constructor (injector:Injector) {
    setTimeout(() => this._appLog = injector.get(AppLog));
  }
  ...
}

Angulars DI本身不支持循環依賴。

ErrorHandler是在提供者之前創建的。 所以我們需要Injector在我們的自定義錯誤處理程序類中進行依賴注入。

@Injectable()
export class MyErrorHandler implements ErrorHandler{
   constructor(private injector: Injector) { } 
  handleError(error: any) {
      let router = this.injector.get(ServiceName);

    }
}

通過Angular cli創建默認服務並檢查第一部分,參見providedIn: 'root',

@Injectable({
  providedIn: 'root',
})
export class CustomService{
  constructor(private otherService: OtherService) { // ok not failed } 
}

有關更多詳細信息,請檢查angular @Injectable-level configuration

@ NgModule級注入器您可以使用非根NgModule的providers元數據選項在模塊級別配置提供程序,以便將提供程序的范圍限制為該模塊。 這相當於在@Injectable()元數據中指定非根模塊,除了通過提供程序提供的服務不是樹可抖動的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM