Angular 6服务和类继承 [英] Angular 6 Services and Class Inheritance

查看:238
本文介绍了Angular 6服务和类继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Angular 6现在有



首先角度定义( 1 ngInjectableDef AppService 函数的属性。然后从 AppService 继承 ChilAppService ,以便子类包含父类的所有属性。最后当angular尝试在 ChildAppService 上定义( 2 ngInjectableDef 属性时,它可以'由于javascript原型继承,它已经存在( 3 )。





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



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



  @Injectable({
providedIn:'root'
})
export class ChildAppService扩展AppService {
static ngInjectableDef = undefined;
constructor(){
super();
this.name ='儿童服务';
}
}



分叉stackblitz



2)或报告github中的问题



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


Angular 6 now has injectable providers which is the new recommended way of injecting services, and it works really well except I'm having a problem when using a service which extends another service. So as an example, suppose I have

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

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

The problem is that no matter what I ask for in a component, the parent class is always injected.

So if you ask for

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

you will still be provided an instance of ParentAppService, which isn't expected.

A very simple workaround would be to just register the providers in your module the old fashioned way, and this works:

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

But that's basically the old way of doing things, and doesn't have the benefits of better tree-shaking and cleaner testing like the new providedIn registration process.

So my question is, what's the right way to do this? Is there a better way to register a provider so I can get the desired behavior (maybe specifying a provider token somehow?).

I've setup a super simple stackblitz example to show what's going on.

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

You'll notice it says "Hello I AM APP SERVICE!" even though the component asked to be provided the child service. If in the app module we register the providers the old way (see the commented out code), all of a sudden the proper provider gets injected.

Thanks for your help!

解决方案

Update:

There is already a pull request for that https://github.com/angular/angular/pull/25033

Original version

The problem: seems new angular treeshakable services don't respect inheritance:

First angular defines(1) ngInjectableDef property on AppService function. Then you inherit ChilAppService from AppService so that child class contains all properties from parent class. And finally when angular tries to define(2) ngInjectableDef property on ChildAppService it can't because it already exists(3) thanks to javascript prototypical inheritance.

In order to fix it you can either

1) workaround it through defining undefined ngInjectableDef property on child service so that it won't read already filled from parent class property and angular will be able to define ngInjectableDef on child class:

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

Forked stackblitz

2) or report issue in github

3) or use composition instead of inheritance as was suggested in comments.

这篇关于Angular 6服务和类继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆