Mat-table Sorting Demo not Working

后端 未结 20 2591
旧巷少年郎
旧巷少年郎 2020-12-02 10:55

I am trying to get the mat-table sorting to work locally, and while I can get the data to show up as expected, clicking on the header row does not do the sortin

相关标签:
20条回答
  • 2020-12-02 11:29
    My solution for this problem is as below - 
    
    
    1. These two lines will go in the same order.
    
        this.dataSource = new MatTableDataSource(myRowDataArray);// this dataSource is used in table tag.
        this.dataSource.sort = this.sort;
    
    
    2. Pass MatTableDataSource object in [dataSource] 
        <table mat-table [dataSource]="dataSource">
        // rest of the table definition here
        </table>
    
    3. By default, the MatTableDataSource sorts with the assumption that the sorted column's name matches the data property name that the column displays.
    
    Example - 
        <ng-container matColumnDef="date" >
              <th class="headers" mat-header-cell  *matHeaderCellDef mat-sort-header>Date</th>
              <td class="data" mat-cell *matCellDef="let row">{{row.date|date}}</td>
        </ng-container>
    
    4. If the table is inside *ngIf,then replace it with [hidden] or some other filter.
    

    I missed the 2nd point.

    Cheers!
    
    0 讨论(0)
  • 2020-12-02 11:30

    If the table is inside *ngIf, it won't be working. It will work if it is changed to [hidden]

    0 讨论(0)
  • 2020-12-02 11:32

    I also hit this issue. Since you need to wait for the child to be defined, you have to implement and use AfterViewInit, not onInit.

      ngAfterViewInit (){
        this.dataSource.sort = this.sort;
      }
    
    0 讨论(0)
  • 2020-12-02 11:33

    I fixed this in my scenario by naming the table data with same name as *matColumnDef For example:

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
      <mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
    </ng-container>
    

    Instead

    <!-- Name Column -->
        <ng-container matColumnDef="userName">
          <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
          <mat-cell *matCellDef="let row"> {{row.name}} </mat-cell>
        </ng-container>
    
    0 讨论(0)
  • 2020-12-02 11:33

    See if you have any javascript errors in the console. It could be that some other thing failed before your sorting initialized.

    0 讨论(0)
  • 2020-12-02 11:35

    One of the reasons MatSort might not work, is when it is added to a dataSource (i.e. this.dataSource.sort = this.sort) before it is defined. There can be multiple reasons for this:

    1. if you add the sort in ngOnInit. At this point the template is not yet rendered, so the MatSort you get with @ViewChild(MatSort, { static: true }) sort: MatSort; is undefined and understandably will not do anything. A solution for this issue is to move this.dataSource.sort = sort to ngAfterViewInit. When ngAfterViewInit is called your component is rendered, and MatSort should be defined.

    2. when you use *ngIf is your template on your table element or one if it's parent elements and this *ngIf causes your table not to be rendered at the moment you try to set the MatSort. For example, if you have *ngIf="dataSource.data.length > 0" on your table element (to only render it if there is data present) and you set this.dataSource.sort = this.sort right after you set this.dataSource.data with your data. The component view will not be rerendered yet, so MatSort will still be undefined.

    In order to get MatSort to work and still conditionally show your table you could decide to replace the *ngIf with [hidden] as stated in multiple other answers. However, if you want to keep your *ngIf statement you can use the following solution. This solution works for Angular 9, I haven't tested it on previous versions so I'm not sure if it works there.

    I found this solution here: https://github.com/angular/components/issues/10205

    Instead of putting:

    @ViewChild(MatSort) sort: MatSort;
    

    use a setter for matSort. This setter will fire once matSort in your view changes (i.e. is defined the first time), it will not fire when you change your sorting by clicking on the arrows. This will look like this:

    @ViewChild(MatSort) set matSort(sort: MatSort) {
        this.dataSource.sort = sort;
    }
    

    If you have other functions that (programmatically) change the sorting, I'm not sure if it will fire again, I haven't tested this. If you wan't to make sure it only sets the sort if the sort was undefined, you can do something like this:

    @ViewChild(MatSort) set matSort(sort: MatSort) {
        if (!this.dataSource.sort) {
            this.dataSource.sort = sort;
        }
    }
    
    0 讨论(0)
提交回复
热议问题