Reusable angular 11 template

250 views Asked by At

I have 2 mat-tabs which each have a table in them, with the same data layout, just a different data source.

<mat-tab-group>
  <mat-tab label="table 1">        
    <table mat-table [dataSource]="dataSource1">       <-- one data source
      <ng-container matColumnDef="col1">
        <th mat-header-cell *matHeaderCellDef></th>
        <td mat-cell *matCellDef="let val"> some Data </td>
      </ng-container>

      <ng-container matColumnDef="col2">
        <th mat-header-cell *matHeaderCellDef></th>
        <td mat-cell *matCellDef="let val"> some Data </td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="['col1', 'col2']"></tr>
      <tr mat-row *matRowDef="let row; columns: ['col1', 'col2'];"></tr>
    </table>
  </mat-tab>
  <mat-tab label="table 2">        
    <table mat-table [dataSource]="dataSource2">       <-- another data source
      <ng-container matColumnDef="col1">
        <th mat-header-cell *matHeaderCellDef></th>
        <td mat-cell *matCellDef="let val"> some Data </td>
      </ng-container>

      <ng-container matColumnDef="col2">
        <th mat-header-cell *matHeaderCellDef></th>
        <td mat-cell *matCellDef="let val"> some Data </td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="['col1', 'col2']"></tr>
      <tr mat-row *matRowDef="let row; columns: ['col1', 'col2'];"></tr>
    </table>
  </mat-tab>
</mat-tab-group>

As you can see the rows and columns are exactly the same, so I wanted to reuse the table template as below:

<table mat-table [dataSource]="dataSource2">
  <ng-container *ngTemplateOutlet="tableContent"></ng-container>
</table>

...

<ng-template #tableContent>
 <ng-container matColumnDef="col1">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let val"> some Data </td>
  </ng-container>

  <ng-container matColumnDef="col2">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let val"> some Data </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="['col1', 'col2']"></tr>
  <tr mat-row *matRowDef="let row; columns: ['col1', 'col2'];"></tr>
</ng-template>

With this I get:

Error: Missing definitions for header, footer, and row; cannot determine which columns should be rendered.

How can I define the template once?

1

There are 1 answers

2
StPaulis On

Why don't you create a MyTableComponent and just receive your data as input?

You final HTML should be like this:

<mat-tab-group>
  <mat-tab label="table 1">        
    <my-table [data]="dataSource1"></my-table>
  </mat-tab>
  <mat-tab label="table 2">        
    <my-table [data]="dataSource2"></my-table>
  </mat-tab>
</mat-tab-group>

Either

If you persist with the ngTemplateOutlet solution, maybe it could work if you add the table tag inside the template and pass the data inside the templateOutlet (Read: How to Use NgTemplateOutlet and search for Passing data to ngTemplateOutlet)