Angular Material 2 DataTable Sorting with nested objects

前端 未结 11 886
孤街浪徒
孤街浪徒 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 17:43

    It's trying to sort by element['project.name']. Obviously element doesn't have such a property.

    It should be easy to create a custom datasource that extends MatTableDatasource and supports sorting by nested object properties. Check out the examples in material.angular.io docs on using a custom source.

    0 讨论(0)
  • 2020-11-29 17:43

    I had the same issue, by testing the first proposition I had some errors, I could fixe it by adding "switch (property)"

    this.dataSource.sortingDataAccessor =(item, property) => {
        switch (property) {
        case 'project.name': return item.project.name;
    
        default: return item[property];
        }
      };
    
    0 讨论(0)
  • 2020-11-29 17:44

    I like @Hieu_Nguyen solutions. I'll just add that if you use lodash in you project as I do then the solution translates to this:

    import * as _ from 'lodash';
    
    this.dataSource.sortingDataAccessor = _.get; 
    

    No need to reinvent the deep property access.

    0 讨论(0)
  • 2020-11-29 17:49

    It was hard to find documentation on this, but it is possible by using sortingDataAccessor and a switch statement. For example:

    @ViewChild(MatSort) 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)
  • 2020-11-29 17:49

    Just add this to your data source and you will be able to access the nested object

    this.dataSource.sortingDataAccessor = (item, property) => {
        // Split '.' to allow accessing property of nested object
        if (property.includes('.')) {
            const accessor = property.split('.');
            let value: any = item;
            accessor.forEach((a) => {
                value = value[a];
            });
            return value;
        }
        // Access as normal
        return item[property];
    };
    
    0 讨论(0)
  • 2020-11-29 18:00

    I use a generic method which allows you to use a dot.seperated.path with mat-sort-header or matColumnDef. This fails silently returning undefined if it cannot find the property dictated by the path.

    function pathDataAccessor(item: any, path: string): any {
      return path.split('.')
        .reduce((accumulator: any, key: string) => {
          return accumulator ? accumulator[key] : undefined;
        }, item);
    }
    

    You just need to set the data accessor

    this.dataSource.sortingDataAccessor = pathDataAccessor;
    
    0 讨论(0)
提交回复
热议问题