如何使用 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;
}
}
检查我对你问题的修复
使用 (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() {
}
}
我知道要使用 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;
}
}
检查我对你问题的修复
使用 (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() {
}
}