Angular Material表格中如何为每个对象仅调用一次接口方法
实现方案
核心逻辑
你之前的写法出问题是两个原因:
- Angular变更检测会反复执行模板中的方法表达式,导致接口无限调用
- 你的请求是异步方法,subscribe内部的return无法同步返回值给模板
我们通过缓存已请求数据+仅在分页/初始化时批量请求当前页数据的方案解决,完全满足你每个matricula仅调用一次接口、仅请求当前展示数据的要求。
步骤1:修改TypeScript逻辑
添加缓存对象、修改请求方法、监听分页事件触发请求,示例代码如下:
// 首先定义缓存对象,键为matricula值,值为接口返回的位置数据 posicionCache: Record<string, any> = {}; // 你的表格数据源,假设用的是MatTableDataSource(Angular Material表格标准用法) dataSource: MatTableDataSource<any>; @ViewChild(MatPaginator) paginator: MatPaginator; // 调整后的请求方法,仅在无缓存时发起请求,结果存入缓存 getPosicion(placa: string): void { // 已有缓存直接跳过,不重复请求 if (this.posicionCache[placa]) return; const matriculaParams: MatriculaBuscada = { action: "ultima_posicion", matricula: placa }; this.posicionService.posicion(matriculaParams).subscribe(datos => { this.posicionCache[placa] = datos; }); } // 批量加载当前页所有展示项的位置数据 loadCurrentPageData(): void { const pageStart = this.paginator.pageIndex * this.paginator.pageSize; const pageEnd = pageStart + this.paginator.pageSize; // 切片拿到当前页展示的所有matricula数据 const currentPageItems = this.dataSource.data.slice(pageStart, pageEnd); currentPageItems.forEach(item => this.getPosicion(item.matricula)); } ngAfterViewInit(): void { this.dataSource.paginator = this.paginator; // 初始化时加载第一页数据 this.loadCurrentPageData(); // 监听分页切换事件,每次分页后加载新的当前页数据 this.paginator.page.subscribe(() => this.loadCurrentPageData()); }
步骤2:修改模板代码
移除模板中的方法调用,直接读取缓存数据即可:
<ng-container matColumnDef="posicion" style="flex: 0 0 50%;"> <th mat-header-cell *matHeaderCellDef> Ubicación </th> <td mat-cell *matCellDef="let matricula" height=70px> {{posicionCache[matricula.matricula] || '加载中...'}} </td> </ng-container>
可选优化
你可以在请求失败时给缓存对应键存入请求失败的标记,后续遇到该标记就不再重复请求失败的接口,进一步减少无效请求。
内容的提问来源于stack exchange,提问作者Videgain
相关产品推荐
相关产品推荐

