【问题标题】:Is there a way to extend a child component's constructor with a new Injection class without the need to call super()?有没有办法用新的注入类扩展子组件的构造函数而无需调用 super()?
【发布时间】:2020-01-29 14:03:39
【问题描述】:

在 Angular 中,我有从父组件继承的子组件。这个父组件注入了多个类。我想用我在父类中不使用的注入类来扩展子组件。在此扩展之前,不需要实例化构造函数并调用super( *args* )。但是,当我尝试扩展构造函数时,我收到以下错误消息:

派生类的构造函数必须包含“超级”调用

有没有办法在通过注入扩展类时不需要调用超类?如果这个问题有什么不清楚的地方,请告诉我。

父组件

@Component({ template: '' })
export abstract class ParentComponent<T> implements OnInit, OnDestroy {

  constructor(
    protected formBuilder: FormBuilder,
    protected route: ActivatedRoute,
    protected snackBar: MatSnackBar,
    protected location: Location
  ) {
    const routeParams = this.route.snapshot.params;
    if (routeParams && routeParams.id) {
      this.subjectId = this.route.snapshot.params.id;
    }
  }
}

子组件

export class ChildComponent extends ParentComponent<MyT> {
  constructor(
    /** I want to extend with the following service */
    protected myService: Service
  ) {
       // But as I instantiate this constructor, I also need to call super() with the required params
  }
}

问题扩展

扩展我的问题;我不确定超类参数的双重导入并传递它是否是开销。这个问题的主要原因是因为我尽量保持代码干净,并尝试克服重复代码。为了在super调用中提供注入类而重复导入感觉有点没用。

【问题讨论】:

  • 为什么调用 super 对你来说是个问题?也许有不同的解决方案可以实现您的目标。
  • 我不相信有办法,您必须在子构造函数中注入所有父依赖项,并使用 super() 将它们传递给父项。

标签: angular inheritance dependency-injection abstract-class


【解决方案1】:

我想你害怕把所有的东西都注入你的父母。这就是为什么你需要这种行为。恐怕角DI没有这样的选择。您可以做的最好的事情是所有组件的通用样式注入Injector而不是其依赖项,然后通过注入器获取所有依赖项。

 class Parent {
   private myService = this.injector.get(MyService)
     private myService2 = this.injector.get(MyService2)
   constructor(@Inject(INJECTOR) injector: Injector){}
}
class Child extends Parent {
 constructor(@Inject(INJECTOR) injector: Injector) {
 super(injector);
  }
}

如果 Parent 在所有这些情况下都不是组件,则可以在其构造函数中省略 @Inject(INJECTOR)

【讨论】:

  • 在这种情况下,孩子不会有myServicemyService2,对吗?
  • 不,他们是private。至少将它们标记为protected,然后它们将在其所有子项中可用
  • 不,private 很好。我认为这就是 OP 想要的,继承父级的其余属性,但不注入相同的服务。
  • 我认为问题作者不想在后代中重新注入所有相同的服务,因此受保护只是这种情况下的最佳选择
【解决方案2】:

在阅读了您的问题几次后,我不确定您是否理解这一点,因此我将其发布为答案。

你可以扩展你的父类并添加一个服务,但你仍然需要调用父类的构造函数。这是不可避免的。你不需要重新注入任何东西,尽管你仍然需要声明它们,至少。

您孩子的构造函数应该如下所示:

constructor(
  formBuilder: FormBuilder,
  route: ActivatedRoute,
  snackBar: MatSnackBar,
  location: Location,
  protected myService: Service // note the "protected" here but not above
) {
  super(formBuilder, route, snackBar, location);
}

子构造函数的非protected 参数本质上是“传递”,可以说,是对你父母应该注入的声明。没有任何东西被双重注射或类似的东西。

【讨论】:

  • 问题的目标确实是如果你想扩展它,是否需要调用父构造函数。 no 是这个问题的有效答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 2020-01-29
  • 2014-05-29
  • 2019-08-05
  • 2019-11-17
  • 2021-11-11
相关资源
最近更新 更多