如何使用 MatSort 从排序中跳过一行?

How to skip a row from sort using MatSort?

我知道要使用 MatTable 的排序功能,您需要使用

mat-sort-header

但是有没有办法在排序的时候跳过一行呢?

基本上根据上面的示例 table 我只想对第 1 - 3 行中的数据进行排序。

当我使用

mat-sort-header

它还包括排序中的第一行(以红色突出显示)。它可以排除在排序之外吗?谢谢。

这里是Snippet Link

代码如下:

HTML

<table mat-table [dataSource]="dataSource" matSort>       
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Column 1 </th>
    <td mat-cell *matCellDef="let element"> {{element.name}} </td>
  </ng-container>

  <ng-container matColumnDef="column1">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Column 2 </th>
    <td mat-cell *matCellDef="let element"> {{element.col1}} </td>
  </ng-container>

  <ng-container matColumnDef="column2">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Column 3 </th>
    <td mat-cell *matCellDef="let element"> {{element.col2}} </td>
  </ng-container>

  <ng-container matColumnDef="column3">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Column 4 </th>
    <td mat-cell *matCellDef="let element"> {{element.col3}} </td>
  </ng-container>

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

TS

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';

export interface Data {
  name?: string,
  col1?: string,
  col2?: string,
  col3?: string
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  data: Array<Data> = [];
  columns: any[] = ['name', 'column1', 'column2', 'column3'];
  displayedColumns: any[] = [];

  dataSource: MatTableDataSource<Data>;
  @ViewChild(MatSort, { static: true }) sort: MatSort;

  ngOnInit() {
    for(let i = 1; i <= 10; i++){
      this.data.push({
        name: "Row " + i,
        col1: "Data " + i,
        col2: "Data " + i,
        col3: "Data " + i
      });
    }

    this.data.unshift({
      name: '',
      col1: 'Data Summary 1',
      col2: 'Data Summary 2',
      col3: 'Data Summary 3'
    });

    this.dataSource = new MatTableDataSource(this.data);
    this.displayedColumns = this.displayedColumns.concat(this.columns);
  }

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
  }
}

检查我对你问题的修复

Snippet

使用 (matsortchange) 并编写您自己的要求,例如您希望如何对行进行排序:)

html:

<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)" matSortDisableClear  matSortDirection="asc"> 

ts: //添加另一个 属性 可排序到您的模型作为布尔值,因为对于您不想排序的行将其推为假,对于您想要排序的行将其推为真

我添加大小写的原因是 - 例如,如果您将 column1 数据作为数字,那么此解决方案将不起作用,因此您不必将它们转换为小写

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';

export interface Data {
  name?: string,
  col1?: string,
  col2?: string,
  col3?: string,
  sortable?:boolean
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  data: Array<Data> = [];
  columns: any[] = ['name', 'column1', 'column2', 'column3'];
  displayedColumns: any[] = [];

  dataSource: MatTableDataSource<Data>;
  @ViewChild(MatSort, { static: true }) sort: MatSort;

  ngOnInit() {
    for(let i = 1; i <= 5; i++){
      this.data.push({
        name: "Row " + i,
        col1: "Data " + i,
        col2: "Data " + i,
        col3: "Data " + i,
        sortable:true
      });
    }

    this.data.unshift({
      name: '',
      col1: 'Data Summary 1',
      col2: 'Data Summary 2',
      col3: 'Data Summary 3',
      sortable:false
    });

    this.dataSource = new MatTableDataSource(this.data);

    this.displayedColumns = this.displayedColumns.concat(this.columns);
  }
sortData(sort: MatSort): void {
        const data: Array<Data> = this.dataSource.data.slice();
        if (!sort.active || sort.direction === '') {
            this.dataSource.data = data;
            return;
        }

        this.dataSource.data = data.sort((a, b) => {
          if(!a.sortable || !b.sortable){
             return 1
          }
          else{
            let isAsc: boolean = sort.direction === 'asc';
            switch (sort.active) {
                case 'name': return this.compare(a.name.toLowerCase(), b.name.toLowerCase(), isAsc, );
                case 'column1': return this.compare(a.col1.toLowerCase(), b.col1.toLowerCase(), isAsc);
                 case 'column2': return this.compare(a.col2.toLowerCase(), b.col2.toLowerCase(), isAsc);
                  case 'column3': return this.compare(a.col3.toLowerCase(), b.col3.toLowerCase(), isAsc);
                default: return 0;
            }
        }}
        );
        this.dataSource = new MatTableDataSource<Data>(this.dataSource.data);
    }
    compare(a: any, b: any, isAsc: boolean): number {
        if (a < b) {
            return -1 * (isAsc ? 1 : -1);
        } else if (a > b) {
            return 1 * (isAsc ? 1 : -1);
        } else {
            return 0 * (isAsc ? 1 : -1);
        }
    }
  ngAfterViewInit() {

  }
}