angular

Componente hijo Angular2 como datos



(2)

Digamos que tengo dos componentes: parent e child . El HTML se vería así:

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

El resultado final se vería así:

<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>

El componente padre:

@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? } }

¿Cómo accedo a los componentes secundarios desde el padre y obtengo su contenido?

Además, no quiero que los niños se representen automáticamente. Dependiendo de algunas condiciones, puedo elegir no mostrar a ciertos niños.

Gracias.



<ng-content>

Para proyectar contenido a un elemento (transclusión) necesitaría el elemento <ng-content> como

@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">

pero eso no funcionará para su caso de uso porque <ng-content> no produce contenido, solo lo proyecta (funciona como un marcador de posición donde se muestran los elementos secundarios dentro de su plantilla de componentes.

Aunque *ngFor produciría 3 elementos <ng-content> , los elementos *ngFor solo se mostrarían una vez en el primer elemento <ng-content> .

<ng-content> permite usar selectores como

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

donde una plantilla como

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

daría como resultado

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

Un enfoque más flexible y poderoso explicado en Eventos de enlace cuando se usa ngForTemplate en Angular 2 (del comentario de @kemsky)

<template> , @ViewChildren() y *ngForTemplate

Si envuelve los elementos secundarios en etiquetas <template> , puede acceder a ellos usando @ContentChildren() e insertarlos usando *ngFor y *ngForTemplate .

Estoy usando un pequeño truco aquí con el *ngFor interno. Hay un mejor enfoque de trabajo en progreso ( ngTemplateOutlet https://github.com/angular/angular/pull/8021 ya fusionado)

@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 {}

Ejemplo de Plunker

Consulte también Cómo repetir un fragmento de HTML varias veces sin ngFor y sin otro @Component para obtener más ejemplos de ngTemplateOutlet Plunker.

actualizar Angular 5

ngOutletContext fue renombrado a ngTemplateOutletContext

Ver también https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29