2017-02-09 6 views
0

Ich versuche Angular2 zu lernen, habe aber ein bisschen Ärger. Ich habe eine abstrakte Service-Klasse ParentServiceVererbung und Polymorphie mit Service und Providern

export abstract class ParentService { 

} 

und eine andere Service-Klasse aufgerufen, die ParentServiceChildService

export class ChildService extends ParentService { 

} 

Dann eine Komponentenklasse Ich habe input.component

import { Component } from "@angular/core"; 

import { ParentService } from "./service/parent.service"; 

@Component({ 
    selector: 'app-input', 
    templateUrl: './input.component.html' 
}) 
export class InputComponent { 
    constructor(private parentService: ParentService) {} 

} 

genannt genannt erstreckt Und in meinem app.component Ich stelle eine Instanz des ChildService

zur Verfügung
import { Component } from '@angular/core'; 
import { ChildService } from './service/child.service'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
    providers: [ChildService] 
}) 
export class AppComponent { 

} 

Dies funktioniert jedoch nicht. Es baut in Ordnung, aber wenn die App läuft Ich erhalte eine Fehler:

EXCEPTION: Error in ./AppComponent class AppComponent - inline template:4:16 caused by: No provider for ParentService! 

Ist das möglich zu tun? Ich will nur die input.component eine ParentService kennen. Ich möchte nicht, dass es die Implementierung kennt.

+0

Sie sollten dieses Muster vermeiden –

+0

@AluanHaddad können Sie erläutern, warum es schlecht wäre? – eric

+0

Vererbung sollte in jeder Sprache und besonders in JavaScript minimal gehalten werden. Da JavaScript keine Schnittstellen hat und TypeScript-Schnittstellen strukturell sind, sehe ich viele Leute, die versuchen, Klassen als Schnittstellen zu verwenden. Das ist eine schreckliche Übung. Sie sollten auf Schnittstellen und nicht auf Implementierungen programmieren. Dies gilt auch für Sprachen, denen manifeste Schnittstellen fehlen. –

Antwort

2

Sie können nicht erwarten, dass Angular2 Unterklassen automatisch mit der ursprünglichen Klassendeklaration verbindet. Was ist, wenn Sie 2 Unterklassen DogService und CatService haben, die beide AnimalService in providers deklariert deklarieren, welche sollte verwendet werden?

Stattdessen müssen Sie es explizit angeben:

providers: [{provide: ParentService, useClass: ChildService}] 

Dokumentation: https://angular.io/docs/ts/latest/guide/dependency-injection.html

2

Es ist möglich, aber mit ein wenig hinaus.

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
    styleUrls: ['./app.component.css'], 
    providers: [{provide: ParentService, useClass: ChildService}] 
}) 
export class AppComponent { 

} 

Die gotcha hier ist, dass DI in Winkel 2 nicht versuchen wird, irgendwelche Beziehungen zwischen Klassen abzuleiten. Also, standardmäßig, um ParentService injizieren Sie müssen ParentService bereitstellen, Zeitraum. Aber glücklicherweise können wir dieses Verhalten mit dem obigen Konstrukt überschreiben. Er teilt dem DI-Container wörtlich mit, "wenn jemand nach ParentService fragt, erstellen Sie ihn und geben Sie ihm stattdessen eine Instanz von ChildService".

+0

Dies gab mir den Fehler "Kein Provider für ChildService!" jetzt. Muss ich eine Instanz von ChildService von meinem app.module zu meiner app.component hinzufügen? Ich habe es versucht und es funktioniert jetzt. Ich vermute, dass AppComonent die Instanz von ChildService nicht erstellt. – eric

+0

Sorry diesen Kommentar ignorieren. Ich hatte noch ChildService in ein paar Komponenten. Deshalb habe ich den Fehler bekommen. Alles gut jetzt. Vielen Dank! – eric