inheritance - angular2+ - 組件繼承和依賴注入

https://code-examples.net/zh-CN/q/253af47

angular中國 (4)

我有一組angular2組件,應該都會注入一些服務。 我的第一個想法是,最好創建一個超級類並在那裏注入服務。 然後我的任何組件都會擴展該超類,但這種方法不起作用。

簡化示例:

export class AbstractComponent {
  constructor(private myservice: MyService) {
    // Inject the service I need for all components
  }
}

export MyComponent extends AbstractComponent {
  constructor(private anotherService: AnotherService) {
    super(); // This gives an error as super constructor needs an argument
  }
}

我可以通過在每個組件中注入 MyService 並使用該參數進行 super() 調用來解決這個問題,但這肯定是某種荒謬的。

如何正確組織我的組件,以便他們從超類繼承服務?


我可以通過在每個組件中注入MyService並使用該參數進行super()調用來解決這個問題,但這肯定是某種荒謬的。

這並不荒謬。 這是構造函數和構造函數注入的工作原理。

每個可注入類都必須將依賴項聲明爲構造函數參數,如果超類也具有依賴項,則這些類也需要在子類的構造函數中列出,並通過 super(dep1, dep2) 調用傳遞給超類。

繞過注射器並獲得依賴性勢在必行具有嚴重的缺點。

它隱藏了使代碼難以閱讀的依賴關係。
它違反了一個熟悉Angular2 DI如何工作的人的期望。
它打破了離線編譯,生成靜態代碼以替換聲明性和命令性DI,以提高性能並減少代碼大小。


如果已從第三方插件獲取父類(並且您無法更改源),則可以執行以下操作:

import { Injector } from '@angular/core';

export MyComponent extends AbstractComponent {
  constructor(
    protected injector: Injector,
    private anotherService: AnotherService
  ) {
    super(injector.get(MyService));
  }
}

或者更好的方法(在構造函數中只保留一個參數):

import { Injector } from '@angular/core';

export MyComponent extends AbstractComponent {
  private anotherService: AnotherService;

  constructor(
    protected injector: Injector
  ) {
    super(injector.get(MyService));
    this.anotherService = injector.get(AnotherService);
  }
}

更新的解決方案,通過使用全局注入器來防止生成myService的多個實例。

import {Injector} from '@angular/core';
import {MyServiceA} from './myServiceA';
import {MyServiceB} from './myServiceB';
import {MyServiceC} from './myServiceC';

export class AbstractComponent {
  protected myServiceA:MyServiceA;
  protected myServiceB:MyServiceB;
  protected myServiceC:MyServiceC;

  constructor(injector: Injector) {
    this.settingsServiceA = injector.get(MyServiceA);
    this.settingsServiceB = injector.get(MyServiceB);
    this.settingsServiceB = injector.get(MyServiceC);
  }
}

export MyComponent extends AbstractComponent {
  constructor(
    private anotherService: AnotherService,
    injector: Injector
  ) {
    super(injector);

    this.myServiceA.JustCallSomeMethod();
    this.myServiceB.JustCallAnotherMethod();
    this.myServiceC.JustOneMoreMethod();
  }
}

這將確保MyService可以在任何擴展AbstractComponent的類中使用,而無需在每個派生類中注入MyService。

這個解決方案有一些缺點(請參閱我原始問題下面的@GünterZöchbauer的Ccomment):

  • 當有許多不同的服務需要在許多地方注入時,注入全局注入器只是一種改進。 如果您只有一個共享服務,那麼在派生類中注入該服務可能更好/更容易
  • 我的解決方案和他提議的替代方案都有缺點,它們使得更難以確定哪個類依賴於什麼服務。

有關Angular2中依賴注入的書面解釋,請參閱此博客文章,這有助於我解決問題: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.htmlhttp://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html


根據我的理解,爲了從基類繼承,首先需要實例化它。 爲了實例化它,你需要傳遞它的構造函數所需的參數,因此你通過super()調用將它們從子節點傳遞給父節點,這樣纔有意義。 注射器當然是另一種可行的解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章