【问题标题】:Angular 6 Services and Class InheritanceAngular 6 服务和类继承
【发布时间】:2018-05-10 00:09:52
【问题描述】:

Angular 6 现在有injectable providers,这是新推荐的注入服务的方法,它工作得非常好,除非我在使用扩展另一个服务的服务时遇到问题。举个例子,假设我有

@Injectable({
  providedIn: 'root'
})
export class ParentAppService { ... }

@Injectable({
  providedIn: 'root'
})
export class ChildAppService extends ParentAppService { ... }

问题是,无论我在组件中要求什么,父类总是被注入。

所以如果你要求

constructor(private childAppService: ChildAppService) { ... }

仍然会为您提供 ParentAppService 的实例,这不是预期的。

一个非常简单的解决方法是在您的模块中以老式方式注册提供程序,这很有效:

@NgModule({
 providers: [AppService, ChildAppService]
})

但这基本上是旧的做事方式,并且不像新提供的注册过程那样具有更好的 tree-shaking 和更清洁的测试的好处。

所以我的问题是,这样做的正确方法是什么?有没有更好的方法来注册提供者,以便我可以获得所需的行为(也许以某种方式指定提供者令牌?)。

我已经设置了一个超级简单的 stackblitz 示例来展示正在发生的事情。

https://stackblitz.com/edit/angular-lacyab?file=src%2Fapp%2Fapp.component.ts

您会注意到它显示“您好,我是应用服务!”即使组件要求提供子服务。如果在 app 模块中我们以旧方式注册提供程序(请参阅注释掉的代码),突然间适当的提供程序会被注入。

感谢您的帮助!

【问题讨论】:

  • 使用组合而不是继承?

标签: javascript angular


【解决方案1】:

更新:

已经有一个针对该https://github.com/angular/angular/pull/25033的拉取请求

原版

问题:似乎新的 angular treeshakable 服务不尊重继承:

AppService 函数上的第一个角度定义(1ngInjectableDef 属性。然后你从AppService 继承ChilAppService,这样子类就包含了父类的所有属性。最后,当 Angular 尝试在 ChildAppService 上定义(2ngInjectableDef 属性时,由于 javascript 原型继承,它不能因为它已经存在(3)。

为了修复它,您可以

1) 通过在子服务上定义未定义的 ngInjectableDef 属性来解决它,这样它就不会从父类属性中读取已经填充的内容,并且 Angular 将能够在子类上定义 ngInjectableDef

@Injectable({
  providedIn: 'root'
})
export class ChildAppService extends AppService {
  static ngInjectableDef = undefined;
  constructor() {
    super();
    this.name = 'CHILD SERVICE';
  }
}

Forked stackblitz

2) 或在 github 中报告问题

3) 或者按照 cmets 中的建议使用组合而不是继承。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2019-02-26
    • 2016-03-29
    • 2014-09-07
    • 2014-07-10
    • 2021-03-13
    相关资源
    最近更新 更多