2016-12-20 3 views
0

Ich habe die folgende Struktur von verschachtelten Komponenten.Chaining Einbindung in verschachtelten Komponenten

<app-root> 
    <app-comp-1> 
     <app-comp-2> 
     </app-comp-2> 
    </app-comp-1> 
    <app-root> 

Ich möchte Inhalte in das letzte untergeordnete Element (app-comp-2) übertragen. Also, ich brauche so etwas.

<app-comp-1> 
    <app-comp-2> 
     <ng-content></ng-content> 
    </app-comp-2> 
</app-comp-1> 

Aber in der App-Root-Komponente ist nur die Komponente app-comp-1 verfügbar. Also, das ist der Ort, an den ich meine Inhalte übertragen muss.

<app-root> 
    <app-comp-1> 
     <content-I-want-to-transclude></content-I-want-to-transclude> 
    </app-comp-1> 
</app-root> 
--------------------------- 
<app-comp-1> 
    <ng-content></ng-content> 
    <app-comp-2> 
     ... 
    </app-comp-2> 
</app-comp-1> 

Also ich brauche eine Lösung, um die Inhalte zu erhalten, die in die erste Komponente transkludiert worden ist, und gibt sie an die zweite nach unten.

Plunker

Antwort

0

Transclusion nicht in Wurzelelement unterstützt wird, finden this.

Hoewever können Sie ng-Gehalt in allen componnets, um übergeben Sie den Inhalt hinzufügen.

@Component({ 
    selector: 'my-app', 
    template: ` 
    <app-comp-1> 
    <app-comp-2> 
     <app-comp-3> 
     Hello World 
     </app-comp-3> 
    </app-comp-2> 
    </app-comp-1> 
    ` 
}) 
export class AppComponent { name = 'Angular'; } 

@Component({ 
    selector: 'app-comp-1', 
    template: ` 
    app-comp-1 
    <ng-content></ng-content> 
    ` 
}) 
export class AppComponent1 { } 

@Component({ 
    selector: 'app-comp-2', 
    template: ` 
    app-comp-2 
    <ng-content></ng-content> 
    ` 
}) 
export class AppComponent2 { } 

@Component({ 
    selector: 'app-comp-3', 
    template: ` 
    app-comp-3 
    <ng-content></ng-content> 
    ` 
}) 
export class AppComponent3 { } 

Siehe hierzu Plunker.

Hoffe das hilft !!

+0

Danke für den Plünderer! Aber ich muss mich mit einem Fall beschäftigen, in dem die "Hallo Welt" nur in app-comp-1 verfügbar ist, und ich möchte es von dort bekommen und es an app-comp-3 weitergeben. Der Inhalt muss nur in der ersten Komponente verfügbar sein –

+0

Kannst du den Plunker mit deinem Use Case forkieren und aktualisieren und zu der Frage hinzufügen? –

+0

[Plunker] (http://plnkr.co/edit/8mnjc2t9TTK2hmJJH41z?p=preview). Vielen Dank –

2

Ich hatte ein ähnliches Problem, wobei ich eine Karte Komponente, die eine Kind-Pass-Header-Komponente sowie eine Auswahl für den Kartenkörper hat.

Die Karten-Header-Komponente hat eine umschaltbare Schaltfläche, die geschlossenen Aktionen, für die Karten offen/entsendet.

I benötigte dann die Fähigkeit, zusätzliche Tasten in die Karten-Header-Komponente von der übergeordneten Komponente über die Kartenkomponente passiert

ich es auf jeder Ebene durch Hinzufügen Selektoren gelöst.

Zuerst habe ich eine gemeinsame Card-Header-Komponente erstellt, die es mir ermöglicht, einen einzigen Code zu verwenden, der den Inhalt der Karte umschaltet, indem er Aktionen an den NgRx-Store schickt, der ein Array von versteckten Karten enthält Eingabeeigenschaft).

Die Karte-Header-Komponente abonniert hat den Laden und sendet ein Ereignis an die übergeordnete Komponente, wenn der toggled Status

@Component({ 
    selector: 'po-card-header', 
    template: ` 
    <div class="card-header"> 

     <span class="text-uppercase">{{ header }}</span> 

     <div class="header-controls"> 
     <ng-content select=[card-header-option]></ng-content> 
     <ng-content select=[header-option]></ng-content> 

     <span class="header-action" (click)="onTogglePanel()"> 
     <i class="fa" [ngClass]="{ 'fa-caret-up': !collapsed, 'fa-caret-down': collapsed}"></i> 
     </span> 

     </div> 

    </div> 
    ` 
}) 
export class CardHeaderComponent implements OnInit, OnDestroy { 
    ... 
    @Input() name: string; 
    @Output() togglePanel = new EventEmitter<boolean>(); 

    collapsed$: Observable<boolean>; 
    collapsedSub: Subscription; 

    constructor(private store: Store<State>) { 
    this.collapsed$ = this.store.select(state => getPanelCollapsed(state, this.name); 
    } 

    ngOnInit(): void { 
    this.collapsedSub = this.collapsed$.subscribe(collapsed => { 
     this.collapsed = collapsed; 
     this.togglePanel.emit(collapsed); 
    }); 
    } 

    .... unsubscribe on destroy. 
} 

Hinweis Änderungen der Header 2 ng-content Abschnitte aufweist.

Der header-option Selektor ist für alle anderen Symbole ich hinzufügen möchte, wenn ich diese Komponente explizit zum Beispiel verwenden

<div class="card"> 

    <po-card-header> 
    ... 
    <span header-option class="fa fa-whatever" (click)="doSomething()"></span> 
    </po-card-header> 

    ... 

</div> 

Mein neues Symbol wird neben dem Standard-Toggle-Symbol in der Kopfzeile sitzen. Der zweite card-header-option Selektor ist für Root-Komponenten, die die Kartenkomponente verwenden, nicht die Kartenkopfkomponente, aber dennoch zusätzliche Symbole in die Kopfzeile übertragen möchten.

@Component({ 
    selector: 'po-card', 
    template: ` 

    <div class="card"> 
     <po-card-header> 
     ... 
     <ng-content select="[card-header-option] header-option></ng-content> 
     </po-card-header> 

     <div class="card-block"> 
     <ng-content select="[card-body]"></ng-content> 
     </div> 

    </div> 
    ` 
}) 
... 

Der [card-header-option] Selektor alle Elemente mit diesem Attribute auswählen wird, übergeben sie dann in die Karten-Header-Komponente das header-option Attribut

Die endgültige Nutzung meiner Karte Komponente sieht wie folgt aus mit nach unten.

<div> 
    Some component that uses the card 
    <po-card 
    header="Some text to go in the card header" 
    name="a-unique-name-for-the-card"> 

    <span card-header-option class='fa fa-blah header-action'></span> 

    <div card-body> 
     Some content that gets put inside the [card-body] selector on the card component. 
    </div> 

    </po-card> 
</div> 

Das Endergebnis ist, dass ich meine benutzerdefinierte Karte Komponente verwenden kann, und die Vorteile der Umschaltfunktion bekommen, dass die Karte-Header-Komponente gibt, sondern auch meine eigenen benutzerdefinierten Aktionen liefern, die auch in übertragenen erhalten die Überschrift

Hoffe, dass Sie das hilfreich finden :-)