Search code examples
angulargenericsconcatenationexpressionreusability

Angular create reusable/generic html-structure


I thought it would be easy, but i cant find any solution for my problem.

So, i want to create a generic table.component. My idea is to give all the information that is needed by doing some expression stuff in html code.

the given data look like this:

  myData: [
    {
      id: 1,
      name: 'name1',
      stuff: 'stuff..'
    },...
]

table.component:

My thought is to use the column identifiers/titles to get the data-informations from the tableData - something like this: {{row}}.{{item}} // item is the column identifier, otherwise item is the identifier for the data-values and row is the current element out of the loop.

@Component({
  selector: 'app-table',
  template: `
    <div class="{{tableName}}-header">
      <h3>{{tableName}}</h3>
    </div>
    <div class="{{tableName}}-content">
      <table mat-table [dataSource]="tableData" class="">
       
        <div *ngFor="let item of displayedColumns">
          <ng-container matColumnDef="{{item}}">

            <th mat-header-cell *matHeaderCellDef> {{item}} </th>
            <td mat-cell *matCellDef="let row"> {{row}}.{{item}} </td>

          </ng-container>
        </div>
        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
      </table>
    </div>
  `,

  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit {
  @Input() tableName: string;
  @Input() tableData: any;

  displayedColumns: string[] = ['id',  'name', 'stuff'];

  // doing in other component.
  tableData = myData;

Is there a (easy) way to concatenate two expression to create a new expression? (parse two expression to string, concatenate them to a dotted notation and parse them back to an expression?)


Solution

  • To dynamically access the row object's property, you have to use bracket notation instead of dot notation:

    <td mat-cell *matCellDef="let row"> {{row[item]}} </td>
    

    Also, since you're using Angular Material, you might be interested in using their MatTextColumn instead: https://material.angular.io/components/table/api#MatTextColumn