angulartypescripthtml-tableangular-materialangular-binding

Angular | Generic data table deep level binding using angular material without using angular function


I created a generic table component using angular material. I have metadata for column representation as below.

`tableColumnBinding: TableColumnMetadata[] = [
 {
  title: 'product.id',
  name: 'id',
  type: 'link',
  path: 'product.status.value', //deep level path
  icon: '',
  isDeepBinding: true
}]`

HTML View:

`<ng-container *ngFor="let columnMetadata of tableMetadata" [matColumnDef]="columnMetadata.name">
<th mat-header-cell *matHeaderCellDef> {{ columnMetadata.title | transloco}} </th>
<td mat-cell *matCellDef="let element ">

<div *ngIf="columnMetadata.isDeepBinding; else isNotDeepBinding">
  <span
   (click)="onNavigateButtonClick(element)">
    {{columnDeepDataBinding(element, columnMetadata.path)}}</span>
 </div>
 </td>
</ng-container>`

I am looking for an alternative solution to replace columnDeepDataBinding(element, columnMetadata.path) with something like element[columnMetadata.path] or any other better solution without using angular function to render data.


Solution

  • You can achieve it by using pipe, Create reusable pipe as like below

    @Pipe({
       name: 'resolve'
    })
    
    export class ResolvePipe implements PipeTransform {
       transform(element: any, path: string): any {
        if (element != null && path != null) {
            return path.split('.').reduce((prev, curr) => {
                return prev ? prev[curr] : null;
            }, element);
        }
    
        return null;
      }
    }
    

    import pipe into your module and put it like

     <span (click)="onNavigateButtonClick(element)">
        {{element | resolve : columnMetadata.path)}}
     </span>
    

    Hope it's works for you

    Thanks!.