Angular Material 2 DataTable Sorting with nested objects

前端 未结 11 887
孤街浪徒
孤街浪徒 2020-11-29 17:25

I have a normal Angular Material 2 DataTable with sort headers. All sort are headers work fine. Except for the one with an object as value. These doesn\'t sort at all.

相关标签:
11条回答
  • 2020-11-29 18:00

    Another alternative, that no one threw out here, flatten the column first...

    yourData.map((d) => 
       d.flattenedName = d.project && d.project.name ? 
                         d.project.name : 
                         'Not Specified');
    
    this.dataSource = new MatTableDataSource(yourData);
    

    Just another alternative, pros and cons for each!

    0 讨论(0)
  • 2020-11-29 18:02

    I customized for multiple nested object level.

    this.dataSource.sortingDataAccessor =
      (data: any, sortHeaderId: string): string | number => {
        let value = null;
        if (sortHeaderId.includes('.')) {
          const ids = sortHeaderId.split('.');
          value = data;
          ids.forEach(function (x) {
            value = value? value[x]: null;
          });
        } else {
          value = data[sortHeaderId];
        }
        return _isNumberValue(value) ? Number(value) : value;
      };
    
    0 讨论(0)
  • 2020-11-29 18:05

    You can write a function in component to get deeply property from object. Then use it in dataSource.sortingDataAccessor like below

    getProperty = (obj, path) => (
      path.split('.').reduce((o, p) => o && o[p], obj)
    )
    
    ngOnInit() {
      this.dataSource = new MatTableDataSource(yourData);
      this.dataSource.sortingDataAccessor = (obj, property) => this.getProperty(obj, property);
      this.dataSource.sort = sort;
    }
    
    columnDefs = [
      {name: 'project.name', title: 'Project Name'},
      {name: 'position', title: 'Position'},
      {name: 'name', title: 'Name'},
      {name: 'test', title: 'Test'},
      {name: 'symbol', title: 'Symbol'}
    ];
    

    And in html

    <ng-container *ngFor="let col of columnDefs" [matColumnDef]="col.name">
          <mat-header-cell *matHeaderCellDef>{{ col.title }}</mat-header-cell>
          <mat-cell *matCellDef="let row">
            {{ getProperty(row, col.name) }}
          </mat-cell>
      </ng-container>
    
    0 讨论(0)
  • 2020-11-29 18:07

    The answer as given can even be shortened, no switch required, as long as you use the dot notation for the fields.

    ngOnInit() {
      this.dataSource = new MatTableDataSource(yourData);
    
      this.dataSource.sortingDataAccessor = (item, property) => {
         if (property.includes('.')) return property.split('.').reduce((o,i)=>o[i], item)
         return item[property];
      };
    
      this.dataSource.sort = sort;
    }
    
    0 讨论(0)
  • 2020-11-29 18:08

    Use MatTableDataSource Check complete MatSort issue solution

    in HTML

        <ng-container matColumnDef="createdDate" @bounceInLeft>
          <th mat-header-cell *matHeaderCellDef mat-sort-header class="date"> Created date
          </th>
              <td mat-cell *matCellDef="let element" class="date"> {{element.createdDate
               | date :'mediumDate'}} </td>
       </ng-container>
    
      <ng-container matColumnDef="group.name">
        <th mat-header-cell *matHeaderCellDef mat-sort-header class="type"> Group </th>
        <td mat-cell *matCellDef="let element" class="type"> {{element.group.name}} </td>
      </ng-container>
    
    @ViewChild(MatSort, { static: true }) sort: MatSort;
    
        ngOnInit() {
          this.dataSource = new MatTableDataSource(yourData);
          this.dataSource.sortingDataAccessor = (item, property) => {
        switch(property) {
          case 'project.name': return item.project.name;
          default: return item[property];
        }
      };
      this.dataSource.sort = sort;
    }
    
    0 讨论(0)
提交回复
热议问题