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()调用将它们从子节点传递给父节点,这样才有意义。 注射器当然是另一种可行的解决方案。

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