typescript - Angular 7+ - Injektion och underklass
Normalt, när du har en injicerbar tjänst som du vill använda, skriver du något liknande detta:
export class MyClass {
constructor(
private _myservice: MyService)
{ }
[...]
}
Tyvärr, när du utökar MyClass, behöver barnkonstruktören, när den anropar super, injicera samma tjänst.
export class MyClassSon extends MyClass {
constructor()
{
super(); <<<---- ERROR!!!!
}
Jag är förvirrande. Jag använder SuperClass för att låta subklassen få tillgång till injicerbara tjänster utan att injicera dem själva.
Den bästa lösningen jag hittade är Injector:
export class MyClass {
constructor(
injector: Injector)
{
this._myservice = injector.get(MyService);
this._fooservice = injector.get(FooService);
//others services...
}
}
export class MyClassSon extends MyClass {
constructor(injector: Injector)
{
super(injector);
//I can use any other services
}
Detta minskar komplexiteten i super-anropet men jag är fortfarande förbannad över att jag måste göra detta trick.
Finns det ett annat sätt att injicera något i en klass utan att använda konstruktorn så att jag kan hålla den så ren som möjligt och endast för specifik komponentinitialisering?
Svar #1
Om du absolut vill hålla din konstruktor ren kan du använda injector från en statisk fält av din CoreModule (till exempel). Detta rekommenderas inte men det fungerar.
Först bör du hämta din Injector från din CoreModule/AppModule (root)
export class CoreModule {
public static injector: Injector;
public constructor(injector: Injector) {
CoreModule.injector = injector;
}
}
inuti MyClass
export class MyClass {
public constructor() {
this.myService = CoreModule.injector.get(MyService)
}
}
inuti MyClassSon
export class MyClassSon extends MyClass {
public constructor() {
super(); // required for invoke parent build
}
}
du kan använda ett annat alternativ inuti MyClass som inte behöver anropa super()-konstruktorn från barnet.
export class MyClass implements OnInit {
public ngOnInit() {
this.myService = CoreModule.injector.get(MyService)
}
}
men med den sista var försiktig så att du inte överskriver ngOnInit-metoden i barnet utan att anropa förälderns.
Denna lösning följer inte bästa praxis men fungerar bra.
Redigera
Arbeta med abstrakt klass.
export abstract class MyClass {
protected abstract get myService();
}
export class MyClassSon extends MyClass {
protected get myService() {
return this._myService;
}
public construction(private _myService: MyService) {
}
}
