Mat-table自定义过滤对student_id/student_name列失效问题求助
Mat-table自定义过滤异常问题求助
Mat-table自定义过滤功能异常:student_id和student_name列无法触发过滤,CA(ca1、ca2等)数值列可正常过滤。
相关代码
Model定义
export class CassData { enroll_id: string; student_id: string; student_name: string; ca1: number; ca2: number; ca3: number; exam: number; total: number; static asFormGroup(cass: CassData): FormGroup { const fg = new FormGroup({ enroll_id: new FormControl(cass.enroll_id), student_id: new FormControl(cass.student_id), student_name: new FormControl(cass.student_name), ca1: new FormControl(cass.ca1), ca2: new FormControl(cass.ca2), ca3: new FormControl(cass.ca3), exam: new FormControl(cass.exam), total: new FormControl(cass.total) }); return fg; } }
cass.component.ts文件
export class CassComponent implements OnInit, AfterViewInit, OnDestroy { dataSource: MatTableDataSource<any>; displayedColumns: string[] = ['student_id', 'student_name', 'ca1', 'ca2', 'ca3', 'exam', 'total', 'delete']; constructor(private _changeDetectorRef: ChangeDetectorRef, private _formBuilder: UntypedFormBuilder, private _cassService: CassService ) { } ngOnInit(): void { // Create the form this.assessmentForm = this._formBuilder.group({ term: [''], subject_code: [''], class_name: [''], cass: this._formBuilder.array([]) }); } getCassData(): void { this.isLoading = true; let sch_code = this.sch_code; let data = this.assessmentForm.getRawValue(); this._cassService.getCassAsFormArray(sch_code, data).subscribe(cass => { if (cass.length > 0) { this.assessmentForm.setControl('cass', cass); this.dataSource = new MatTableDataSource((this.assessmentForm.get('cass') as FormArray).controls); this.dataSource.filterPredicate = (data: FormGroup, filter: string) => { return Object.values(data.controls).some(x => x.value == filter); }; this.assessmentList = true; this.dataSource.sort = this._sort; this.isLoading = false; } else { this.isLoading = false; this.assessmentList = false; } // Mark for check this._changeDetectorRef.markForCheck(); }); } applyFilter(filterValue: string) { this.dataSource.filter = filterValue.toLowerCase(); } }
cass.component.html文件
<div class="w-full"> <form [formGroup]="assessmentForm"> <button (click)="getCassData()" mat-stroked-button> <span class="ml-1">Load Data</span> </button> <input matInput (keyup)="applyFilter($event.target.value)" [autocomplete]="'off'" [placeholder]="'Search students'" [disabled]="!assessmentList" #searchField> </form> <ng-container *ngIf="assessmentList; else noData"> <ng-container formArrayName="cass"> <table mat-table [dataSource]="dataSource" matSort> <!-- ID Column --> <ng-container matColumnDef="student_id"> <th mat-header-cell mat-sort-header *matHeaderCellDef> ID </th> <td mat-cell *matCellDef="let element"> {{element.get('student_id').value}} </td> </ng-container> <!-- Name Column --> <ng-container matColumnDef="student_name"> <th mat-header-cell mat-sort-header *matHeaderCellDef> Name </th> <td mat-cell *matCellDef="let element"> {{element.get('student_name').value}} </td> </ng-container> <!-- CA1 Column --> <ng-container matColumnDef="ca1"> <th mat-header-cell mat-sort-header *matHeaderCellDef> CA1 (10%)</th> <td mat-cell *matCellDef="let element" [formGroup]="element"> <mat-form-field> <input type="number" formControlName="ca1" matInput> </mat-form-field> </td> </ng-container> <!-- CA2 Column --> <ng-container matColumnDef="ca2"> <th mat-header-cell mat-sort-header *matHeaderCellDef> CA2 (10%)</th> <td mat-cell *matCellDef="let element" [formGroup]="element"> <mat-form-field> <input type="number" formControlName="ca2" matInput> </mat-form-field> </td> </ng-container> ... </table> </ng-container> </ng-container> </div>
问题原因及解决方案
问题根源
- 匹配逻辑错误:原
filterPredicate使用==做严格相等匹配,只有输入内容与控件值完全一致时才会命中,不符合用户搜索部分内容的需求,导致字符串列无法匹配。 - 大小写不统一:
applyFilter中将过滤关键词转为小写,但student_id、student_name的控件值未做小写转换,大小写不一致时无法匹配。 - 类型不兼容:数值列(ca1等)的数值与字符串过滤词用
==时会隐式转换,所以能正常匹配;但字符串列没有这个转换,导致匹配失败。
修复代码
修改getCassData中的filterPredicate逻辑:
this.dataSource.filterPredicate = (data: FormGroup, filter: string) => { // 将每个控件的值转为字符串并统一小写,判断是否包含过滤关键词 return Object.values(data.controls).some(control => { const value = control.value?.toString().toLowerCase() || ''; return value.includes(filter); }); };
说明
- 所有控件值转为字符串并小写,确保与过滤词大小写统一;
- 使用
includes实现包含匹配,符合用户搜索部分内容的需求; - 兼容数值和字符串类型的控件值,解决类型不匹配问题。
内容的提问来源于stack exchange,提问作者HardSoft
相关产品推荐
相关产品推荐

