2016-01-02 7 views
14

Ich habe drei Komponenten: App, Eltern und Kind:@ContentChildren wird nicht aufgefüllt werden

App Component

@Component({ 
    selector: 'app', 
    directives: [Parent,Child], 
    template: '<parent><child>hi</child><child>there</child></parent>' 
}) 
export class AppComponent { 
    constructor() { 
    } 
} 

geordnete Komponente

@Component({ 
    selector: 'parent', 
    template: '<div><h1>Parent</h1><ng-content></ng-content></div>' 
}) 
export class Parent { 
    @ContentChildren(Child) children: QueryList<Child>; 
    ngAfterContentInit() { 
     console.log(this.children); 
    } 
} 

Untergeordnete Komponente

@Component({ 
    selector: 'child', 
    template: '<div><h1>Child</h1></div>' 
}) 
export class Child { 
} 

Wie Sie in der übergeordneten Komponente sehen können, habe ich versucht, @ContentChildren zu verwenden, um die Liste der untergeordneten Komponenten zu erhalten, den Child Typen als Selektor. Dies scheint jedoch nicht zu funktionieren - die Inhalts-Child-Liste ist immer undefiniert.

In der ngAfterContentInit()-Methode hätte ich erwartet, dass die untergeordneten Inhalte gefüllt werden.

Fehle ich etwas?

[Update]

es stellt sich heraus, so dass das Problem besteht, wenn alle drei Komponenten in der gleichen Datei (siehe Konsole Debug-Fenster, wo ich Ausgabe des Inhalts Kinder):

Plnkr Demo of Issue

Wenn sie in separaten Dateien sind das Problem weggeht:

Plnkr Demo Working

Normalerweise würde ich alle Komponenten nur für Lernzwecke in derselben Datei speichern. Aber es hat mich neugierig gemacht. Weiß jemand, warum das Verhalten anders ist?

+0

Die Kinder sind im DOM sichtbar? Ich habe es gerade versucht (in Dart) und es funktioniert. Haben Sie einen permissiveren Typ als 'QueryList ' für die Variable wie 'any' versucht. –

+0

@ GünterZöchbauer Ich habe versucht, den Typ zu ändern, aber das Problem ist immer noch da. Es scheint, dass es sich auf alle drei Komponenten bezieht, die sich in derselben Datei befinden. – pixelbits

+0

Ich kann nicht in Dart reproduzieren (wenn das irgendeine Hilfe ist), es funktioniert auch mit allem in einer Datei. –

Antwort

20

Sie müssen forwardRef verwenden, um Klassen zu referenzieren, die noch nicht definiert sind. Siehe this plunk. Denken Sie daran, ES6 classes are not hoisted.

@Component({ 
    selector: 'parent', 
    template: '<div><h1>Parent</h1><ng-content></ng-content></div>' 
}) 
export class Parent { 
    @ContentChildren(forwardRef(() => Child)) children; // <!- HERE 

    ngAfterContentInit() { 
     console.log(this.children); 
     console.log(this.children.length); 
    } 
} 

UPD Mark Rajcok wies einen hervorragenden Artikel über Vorwärtsreferenzen in angular2 (siehe Kommentar unten). Muss gelesen werden: thoughtram.io Forward references in Angular 2.

+0

Das erklärt, warum es in Dart funktioniert. –

+1

+1, schlag mich auf die Post. OP, beachten Sie, dass nur [Child 'vor' Parent' deklarieren] (http://plnkr.co/edit/64OJMwOwEle6wNycwwDz?p=preview) in der gleichen Datei auch funktioniert. – drewmoore

+1

Nur FYI, die Verwendung von 'forwardRef()' wird in der [Dependency Injection Entwickleranleitung] (https://angular.io/docs/ts/latest/guide/dependency- injection) erwähnt.html), am Ende der Seite, im Abschnitt "Anhang: Warum wir eine Klasse pro Datei empfehlen". Der Leitfaden empfiehlt auch, [diesen Blog-Beitrag] zu lesen (http://blog.thoughttram.io/angular/2015/09/03/forward-references-in-angular-2.html), um mehr darüber zu erfahren, wann man 'forwardRef verwenden soll() '. –

Verwandte Themen