Angular 6服务和类继承

Sco*_*and 13 javascript angular

Angular 6现在有注入式提供程序,这是注入服务的新推荐方式,除了我在使用扩展其他服务的服务时遇到问题,它工作得非常好.举个例子,假设我有

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

@Injectable({
  providedIn: 'root'
})
export class ChildAppService extends ParentAppService { ... }
Run Code Online (Sandbox Code Playgroud)

问题在于,无论我在组件中要求什么,都会始终注入父类.

所以,如果你要求

constructor(private childAppService: ChildAppService) { ... }
Run Code Online (Sandbox Code Playgroud)

您仍将获得ParentAppService的实例,这不是预期的.

一个非常简单的解决方法是以旧式方式在模块中注册提供程序,这样可行:

@NgModule({
 providers: [AppService, ChildAppService]
})
Run Code Online (Sandbox Code Playgroud)

但这基本上是旧的做事方式,而且没有像新提供的注册流程那样更好的树木震动和清洁测试的好处.

所以我的问题是,做到这一点的正确方法是什么?是否有更好的方法来注册提供程序,以便我可以获得所需的行为(可能以某种方式指定提供者令牌?).

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

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

你会注意到它说"你好我的APP服务!" 即使该组件要求提供儿童服务.如果在app模块中我们以旧方式注册提供者(请参阅注释掉的代码),突然之间会注入正确的提供者.

谢谢你的帮助!

yur*_*zui 9

更新:

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

原始版本

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

在此输入图像描述

第一个角度定义了函数的(1)ngInjectableDef属性AppService.然后继承ChilAppService,AppService以便子类包含父类的所有属性.最后当angular尝试定义(2)ngInjectableDef属性时,ChildAppService它不能因为它已经存在(3),这归功于javascript原型继承.

在此输入图像描述

为了解决这个问题,你也可以

1)通过ngInjectableDef 在子服务上定义未定义的属性来解决它,以便它不会从父类属性中读取已经填充的,并且angular将能够ngInjectableDef在子类上定义:

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

分叉的stackblitz

2)或报告github中的问题

3)或使用组合而不是评论中建议的继承.