简体   繁体   中英

Angular Material Table: Sorting not working

In my Angular app (using Angular Material) I have several tables.

The strange thing is that, in one case, sorting works, while, in another case, it doesn't.

Here is the table that works:

<table mat-table [dataSource]="dataSource" matSort>

  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef> ID </th>
    <td mat-cell *matCellDef="let row"> {{row.id}} </td>
  </ng-container>

  <ng-container matColumnDef="firstName">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> First Name </th>
    <td mat-cell *matCellDef="let row"> {{row.firstName}} </td>
  </ng-container>

  <ng-container matColumnDef="lastName">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Last Name </th>
    <td mat-cell *matCellDef="let row"> {{row.lastName}} </td>
  </ng-container>

  <ng-container matColumnDef="viewProfile">
    <th mat-header-cell *matHeaderCellDef class="viewProfile"> Profile </th>
    <td mat-cell *matCellDef="let row" class="viewProfile">
      <button mat-icon-button (click)="openProfile(row.id)">
                <mat-icon aria-label="icon-button with a page-view icon">pageview</mat-icon>
              </button>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

</table>

... and here is the table that doesn't work:

<table class="table2" mat-table [dataSource]="dataSource2" matSort>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Project </th>
    <td mat-cell *matCellDef="let row"> {{row.name}} </td>
  </ng-container>
  <ng-container matColumnDef="role">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Role </th>
    <td mat-cell *matCellDef="let row"> {{row.role}} </td>
  </ng-container>
  <ng-container matColumnDef="beginning">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Beginning </th>
    <td mat-cell *matCellDef="let row"> {{row.beginning | date : "mediumDate"}} </td>
  </ng-container>
  <ng-container matColumnDef="end">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> End </th>
    <td mat-cell *matCellDef="let row"> {{row.end | date : "mediumDate"}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns2"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns2;"></tr>
</table>

As you can see, in both cases I use " matSort " (in the table tag) and " mat-sort-header " (for the columns that are supposed to be sortable).

Furthermore, in each case I do the same import in the component.ts file:

import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material';

I just don't get why sorting works in the first case but not in the second. Does anybody have any ideas what's going on here?

Make sure that the column_name in the displayedColumns array,

displayedColumns = [' column_name '];

the html container,

ng-container matColumnDef=" column_name "

and the keys of the dataSource objects,

dataSource = [ {" column_name ": "value"} ];

ALL MATCH PERFECTLY.

This can also be the reason that a specific set of data doesn't work and others do.

Are you sure your second table ( the one where sort is not working ) is not wrapped in a div with *ngIf ? Because that is a common problem, as when the template is rendered, because of the *ngIf, matSort is undefined. Here is how to fix it : Angular 5 Material Data Table sorting not working

There is also another possible issue. Besides that column names have to match the attribute 'matHeaderRowDef' in 'mat-header-row *matHeaderRowDef', the column name also has to match the class field/property name of the content type used in the dataSource attribute.

eg

<mat-table [dataSource]="mySource" matSort>
        <!-- modelViewFieldNameOne has to match the class field/property name! -->
        <ng-container matColumnDef="modelViewFieldNameOne">
            <mat-header-cell  *matHeaderCellDef
                             mat-sort-header>just a column</mat-header-cell>
            <mat-cell *matCellDef="let tableItem">{{ tableItem.getterForMyField }}</mat-cell>
        </ng-container>


// typescript where 'mySource' is kept
mySource = new MatTableDataSource<MyModelViewType>();


// typescript of MyModelViewType
export class MyModelViewType{

   // this is important, it has to match the ng-container matColumnDef attribute!!!
   private modelViewFieldNameOne

   // this getter naming is not important for mat-table attributes
   public get getterForMyField(): string { 
     return this.modelViewFieldNameOne;
   }
}

My mat-table was sorting fine, until the model view type (ie MyModelViewType in the example above) was re-factored but only the field / property name changed, the getter() name was kept, the corresponding table column stopped sorting properly. Once the attribute matched the name it worked again.

I am using: @angluar/cdk 9.2.2

For data loaded using an API call :

It's possible that the sort was set before the data was loaded onto the table; thereby messing up sorting feature.


In that case, change:

** code to insert data into the table **

this.dataSource2.sort = this.sort;

To

** code to insert data into the table **

setTimeout(() => this.dataSource2.sort = this.sort, 2000); // Delay it by 2 seconds.

Where this.sort is:

@ViewChild(MatSort, { static: false }) sort: MatSort;

I know my sort doesn't work when it thinks I mixed in data types. So on the list below it will stop sorting the Value column when it gets to the 587.
在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM