Angular12应用筛选器后MatTable行数不变UI未更新问题
问题根因
你的代码存在两个核心问题导致筛选后表格数据不更新:
getEligibleAnimals仅在组件初始化的ngOnInit中调用一次,后续父组件传递的numberOfAnimals发生变化时,子组件没有监听该输入变更,不会重新请求筛选后的数据。- 筛选条件流
targetingCriteria$后使用了take(1)操作符,只会读取第一次的筛选条件,后续用户修改筛选参数时不会触发新的接口请求,永远返回首次查询的全量数据。
解决步骤
1. 监听输入参数numberOfAnimals的变化
给组件实现OnChanges生命周期钩子,检测到numberOfAnimals更新时自动重新拉取数据:
import { Component, Input, OnInit, OnChanges, SimpleChanges, OnDestroy } from '@angular/core'; import { Subject, takeUntil, switchMap } from 'rxjs'; // ... 其他原有引入 export class AnimalsDropdownComponent implements OnInit, OnChanges, OnDestroy { // ... 原有变量定义 private destroy$ = new Subject<void>(); // 用于清理订阅防止内存泄漏 ngOnChanges(changes: SimpleChanges): void { // 非首次变更时触发数据刷新 if (changes['numberOfAnimals'] && !changes['numberOfAnimals'].firstChange) { this.pageIndex = 0; // 可选优化:筛选后重置到第一页,避免页码溢出无数据展示 this.getEligibleAnimals(); } }
2. 优化数据请求逻辑
去掉take(1)操作符,使用switchMap优化嵌套订阅,同时添加订阅清理逻辑:
getEligibleAnimals(): void { this.loading = true; const num: number = this.pageSize; const start: number = (this.pageIndex * this.pageSize) + 1; this.targetingCriteria$ .pipe( takeUntil(this.destroy$), // 组件销毁时自动取消订阅 switchMap((c: any) => this.eligibleAnimalsSvc.get(true, c, c.animalId, num, start)) ) .subscribe((response: CollectionResponse<SearchAnimalsResponse>) => { this.resultsLength = response.total; this.dataSource.data = response.list; this.loading = false; this.cdr.detectChanges(); }); } // 组件销毁时释放资源 ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); }
可选补充:前端本地筛选方案
如果你的筛选逻辑不需要调用后端接口,是在已拿到的全量数据中做本地筛选,可以直接使用MatTableDataSource自带的筛选能力,不需要重新发请求:
// 筛选条件变化时调用,filterValue为你要筛选的关键词 applyFilter(filterValue: string) { this.dataSource.filter = filterValue.trim().toLowerCase(); }
还可以自定义筛选规则:
// ngOnInit中配置自定义筛选逻辑 ngOnInit() { this.dataSource.filterPredicate = (data: any, filter: string) => { // 示例:按动物类型筛选 return data.animalType.toLowerCase().includes(filter); }; this.getEligibleAnimals(); }
内容的提问来源于stack exchange,提问作者Bodrov
相关产品推荐
相关产品推荐

