Home > Software design >  Content projection works only for last usage
Content projection works only for last usage

Time:11-12

I need to add the same table in multiple elements.

I have a parent components that contains the table, a component for the table and a component for the table rows.

export class ParentComponent {
    @Input() table: CustomTableComponent;
}

<div>
    <ng-container *ngTemplateOutlet="table.template"></ng-container>
</div>

export class CustomTableComponent implements AfterContentInit {
    @ViewChild(TemplateRef, { static: true }) template: TemplateRef<any>;
    @ContentChildren(RowComponent) inputRows: QueryList<RowComponent>;

    rows: RowComponent[];

    constructor() {
    }

    ngAfterContentInit(): void {
        this.rows = this.inputRows.toArray();
    }
}

<ng-template>
    <table>
        <thead>
            <tr>
                <td>Col1</td>
                <td>Col2</td>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let row of rows">
                <ng-container *ngTemplateOutlet="row.template"></ng-container>
            </tr>
        </tbody>
    </table>
</ng-template>

export class RowComponent {
    @ViewChild(TemplateRef, { static: true }) template: TemplateRef<any>;

    constructor() {
    }
}

<ng-template>
    <td><ng-content select="[label=col1]"></ng-content></td>
    <td><ng-content select="[label=col2]"></ng-content></td>
</ng-template>

Calling component angular:

@ViewChild(CustomTable) customTable: CustomTable;

Calling component html:

<parent [table]="customTable"/>
<parent [table]="customTable"/>
<parent [table]="customTable"/> -------> only this one has content

<custom-table #customTable>
    <row>
        <label label="col1">Col1Row1</label>
        <label label="col2">Col2Row1</label>
    </-row>
    <row>
        <label label="col1">Col1Row2</label>
        <label label="col2">Col2Row2</label>
    </-row>
</custom-table>

The results is that only the third usage of the ParentComponent has any content. All the ParentComponents have 2 rows, but no Col1Row1, Col1Row2, Col2Row1, Col2Row2 content, just empty table cells, I would like for all the tables that are generated to have content.

CodePudding user response:

try this:

<parent [table]="customTableTemplate"/>
<parent [table]="customTableTemplate"/>
<parent [table]="customTableTemplate"/>

<ng-template #customTableTemplate>
<custom-table >
    <row>
        <label label="col1">Col1Row1</label>
        <label label="col2">Col2Row1</label>
    </-row>
    <row>
        <label label="col1">Col1Row2</label>
        <label label="col2">Col2Row2</label>
    </-row>
</custom-table>

</ng-template>
export class ParentComponent {
    @Input() table: TemplateRef;
}
<div>
    <ng-container *ngTemplateOutlet="table"></ng-container> <-- just table, because now it is a template
</div>
  • Related