2016-04-20 30 views
10

Diciamo che ho due componenti: parent e child. Il codice HTML sarebbe simile a questa:Componente figlio angolare2 come dati

<parent title="Welcome"> 
    <child name="Chris">Blue Team</child> 
    <child name="Tom">Red Team</child> 
</parent> 

L'output finale sarà simile:

<h1>Welcome</h2> 
<ul> 
    <li><b>Chris</b> is on the Blue Team</li> 
    <li><b>Tom</b> is on the Red Team</li> 
</ul> 

Il componente principale:

@Component({ 
    selector: 'parent', 
    directives: [ChildComponent], // needed? 
    template: ` 
    <h1>{{title}}</h1> 
    <ul> 
     <li *ngFor="#child of children()">{{child.content}}<li> 
    </ul>` 
}) 
export class ParentComponent { 

    @Input() title; 

    children() { 
     // how? 
    } 

} 

Come accedo i componenti figlio dall'interno del genitore e ottieni il loro contenuto?

Inoltre, non voglio che i bambini vengano automaticamente renderizzati. A seconda delle condizioni, posso scegliere di non mostrare determinati bambini.

Grazie.

+0

E 'possibile achive che, ma è solo troppo lavoro, si può ottenere molto vicino ad esempio [ qui] (http://stackoverflow.com/questions/36730210/binding-events-when-using-a-ngfortemplate-in-angular-2/36732644?noredirect=1#comment61052816_36732644) – kemsky

risposta

12

<ng-content>

Per proiettare il contenuto di un elemento (inclusione) si avrebbe bisogno l'elemento <ng-content> come

@Component({ 
    selector: 'parent', 
    directives: [ChildComponent], // needed? 
    template: ` 
    <h1>{{title}}</h1> 
    <ul> 
     <li *ngFor="letchild of children()"> 
     <ng-content></ng-content> 
     </li> 
    </ul>` 
}) 

<ng-content select="xxx">

ma che non funziona per il vostro caso d'uso a causa <ng-content> non produce contenuti, proietta solo (funziona come un placehoder in cui i bambini vengono visualizzate all'interno del tuo template componenti.

Anche se *ngFor produce 3 elementi <ng-content>, i bambini vengono visualizzati solo una volta nel primo elemento <ng-content>.

<ng-content> permette di utilizzare selettori come

<ng-content select="[name=Chris]"></ng-content> 

in cui un modello di come

<ul> 
    <li> 
    <ng-content select="[name=Chris]"></ng-content> 
    </li> 
</ul>` 

comporterebbe

<h1>Welcome</h2> 
<ul> 
    <li><b>Chris</b> is on the Blue Team</li> 
</ul> 

Un approccio più flessibile e potente spiegato nel Binding events when using a ngForTemplate in Angular 2 (da @ commento di kemsky)

<template>, @ViewChildren(), e *ngForTemplate

Se si avvolgono i bambini in <template> tag è possibile accedervi utilizzando @ContentChildren() e inserirli utilizzando *ngFor e *ngForTemplate.

Qui sto utilizzando un piccolo trucco con interno *ngFor. C'è un lavoro migliore approccio in corso (ngTemplateOutlethttps://github.com/angular/angular/pull/8021 già fuse)

@Component({ 
    selector: 'parent', 
    template: ` 
    <h1>{{title}}</h1> 
    <ul> 
     <li *ngFor="let child of templates"> 
     <!-- with [child] we make the single element work with 
       *ngFor because it only works with arrays --> 
     <span *ngFor="let t of [child]" *ngForTemplate="child"></span> 
     </li> 
    </ul> 
    <div>children:{{children}}</div> 
    <div>templates:{{templates}}</div> 
    ` 
}) 
export class ParentComponent { 

    @Input() title; 
    @ContentChildren(TemplateRef) templates; 
} 

@Component({ 
    selector: 'my-app', 
    directives: [ParentComponent], 
    template: ` 
    <h1>Hello</h1> 
<parent title="Welcome"> 
    <template><child name="Chris">Blue Team</child></template> 
    <template><child name="Tom">Red Team</child></template> 
</parent>  
    `, 
}) 
export class AppComponent {} 

Plunker example

Vedi anche How to repeat a piece of HTML multiple times without ngFor and without another @Component per ulteriori esempi ngTemplateOutlet Plunker.

aggiornamento angolare 5

ngOutletContext stato rinominato in ngTemplateOutletContext

Vedi anche https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29

Problemi correlati