2017-02-15 9 views
1

Ich habe drei Komponenten, wo componentC als Inhalt von componentB erscheint und bekommt componentB DI'ed in seinem Konstruktor.DI und Transclusion

@Component({ 
    selector: 'componentA', 
    template: ` 
    <componentB> 
     <componentC></componentB> 
     <ng-content></ng-content> 
    </componentB>` 
.... 
export class ComponentC { 
    constructor(private cmpB: ComponentB) 

Jetzt benutze ich componentA von einer anderen Komponente und will Einbindung verwenden, um zusätzliche componentC s, um es über die <ng-content>, die ich in componentA ‚s Vorlage setzen zu liefern:

<componentA> 
    <componentC></componentC> 
</componentA> 

Dies ist ein No provider for ComponentB auslöst. Mit <ng-content> habe ich definiert, dass der Inhalt innerhalb <componentB> angezeigt werden sollte, so dass DI in der Lage sein sollte, das ComponentB Objekt zu finden, das das übergeordnete Element des Einfügemarke ist.

Ist dieses Szenario möglich? Erzeugt Angular meine extra ComponentC direkt am Zielort oder zuerst, wo das Markup dann bewegt wird? Gibt es eine Möglichkeit, Anbieter dafür zu konfigurieren?

Antwort

0

Die Einbindung nicht componentC macht ein Kind componentB, bleibt es ein Kind von componentA, gerade dort, wo es innerhalb des DOM geändert wird angezeigt.

Ich sehe keinen einfachen Weg, um die Injektion zu arbeiten.

Sie könnten componentA machen bieten einen Service, wo componentA einen Verweis auf componentB weist

@Component({ 
    ... 
    providers: [ComponentBProviderService], 
class ComponentA { 
    @ViewChild(ComponentB) componentB:ComponentB; 
    constructor(private bProvider: ComponentBProviderService){} 
    ngAfterViewInit() { 
    this.bProvider.component = this.componentB; 
    } 
} 

Wenn ComponentC diesen Dienst spritzt sie Zugang zu componentB bekommen. Es wäre sinnvoll, einen Observable im Dienst zu verwenden, um aktiv zu benachrichtigen , wenn die Referenz verfügbar wird.

class ComponentC { 
    componentB:ComponentB; 
    constructor(bProvider: ComponentBProviderService){ 
    bProvider.componentAvailable.subscribe(val => this.componentB = val); 
    } 
} 
+1

Guter Punkt über die Einschließung, die die Komponentenhierarchie nicht ändert, aber gerade DOM Sachen umherbewegt. Würde es eine andere Lösung geben, die eine Vorlage und eine Komponentenfabrik verwendet, um den Inhalt als Kind von 'componentB' zu instanziieren? – achimha