Vincent Barrault

Projeter un contenu dans une loop avec ng-template

Projeter un contenu dans une loop avec ng-template

Table des matières

Contexte

Si vous voulez projeter plusieurs composants fils du même type dans un componsant parent, le plus souvent ng-content est la solution qu'il vous faut

Mais si vous voulez afficher vos composants fils dans une boucle pour la mise en forme, voici la marche à suivre.

Marqueur d'élément pour composant fils

./child-marker.directive.ts
import { Directive, TemplateRef } from '@angular/core';

@Directive({
    selector: '[childMarker]'
})
export class ChildMarkerDirective {
    public template: TemplateRef<any>;

    constructor(
        private _templateRef: TemplateRef<any>
    ) {
        this.template = this._templateRef;
    }
}

Composant conteneur

./parent.component.ts
import { Component, ContentChildren } from '@angular/core';
import { ChildMarkerDirective } from './child-marker.directive';

@Component({
    selector: 'app-parent',
    template: `
        <ul>
            <li *ngFor="let childElement of childElements">
                <ng-container [ngTemplateOutlet]="childElement.template"></ng-container>
            </li>
        </ul>`,
})
export class ParentComponent {
    @ContentChildren(ChildMarkerDirective) childElements: ChildMarkerDirective;
}

Usage

<app-parent>
    <span *childMarker>Child1</span>
    <span *childMarker>Child2</span>
    <span *childMarker>Child3</span>
</app-parent>

Il est bien sûr possible de remplacer l'élément span par n'importe quel autre élément/composant.

Ici le composant parent n'est qu'une liste ul, mais vous pouvez aussi utiliser la structure qui vous conviendra le mieux.