How to project content of component by some statement (e.g. by input value)

90 views Asked by At

I'm working on the implementation custom table and faced with an issue.

I cannot correctly project column-component content inside table-component.

  • table.component.ts:

    @Component({
        selector: 'app-table',
        template: `
        <table>
        ...
        <tbody>
            <tr
                *ngFor="let row of rows; let i = index">
                <td *ngFor="let column of columns">
                    <ng-container *ngIf="column.key">{{ getCellValue(column.key, row.value) }}</ng-container>
                    <ng-container *ngIf="!column.key">
                        <ng-content select="app-column"></ng-content> <!-- [1] this one show content just in last cell -->
    
                        <ng-container *ngTemplateOutlet="column.contentTemplateRef;"></ng-container> <!-- [2] the same as line above, but another column wrapped in ng-template -->
                    </ng-container>
                </td>
            </tr>
        </tbody>
        ...
        </table>
        `,
        encapsulation: ViewEncapsulation.None,
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class TableComponent implements AfterViewInit, OnDestroy {
        rows: any[];
    
        @ContentChildren(forwardRef(() => TableColumnComponent))
        columns: QueryList<TableColumnComponent>;
    
        getCellValue(key: string, row: any): any {
            return key.split('.').reduce((a, b) => a[b], row);
        }
    
    }
    
  • column.component.ts:

    @Component({
        selector: 'app-column',
        template: `<ng-content></ng-content>`, // [1]
        // template: `<ng-template><ng-content></ng-content></ng-template>`, // [2]
        encapsulation: ViewEncapsulation.None,
        changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class TableColumnComponent {
        @ViewChild(TemplateRef) contentTemplateRef: TemplateRef<any>; // [2]
    }
    

I've added notes in which situation which template I'm using.


In this StackBlitz example you can see how it works. The button rendered just in the last cell in the last column, but I expect that all cells from the last column will render buttons.


My question is how I could correctly render column content?

0

There are 0 answers