You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 8 Material Table删除操作后数据显示异常问题排查

问题分析与解决方案

这个问题不是Material Table的bug,而是模板中使用行索引绑定ngModel导致的索引错位问题,具体原因和修复方法如下:

问题根源

你在模板中通过let i = index获取行索引,然后绑定[(ngModel)]="menu.snacks[i].fruitId"和[(ngModel)]="menu.snacks[i].drinkId"。但当你标记某个条目为deleted: true并过滤数据源后:

  • 原来的menu.snacks数组并没有删除元素,只是menuTableSource的数据源变成了过滤后的子集
  • 表格的行索引i会重新从0开始计数,但menu.snacks的原始索引并没有改变
  • 这就导致表格行的索引和menu.snacks的实际索引不再匹配,最终出现“删除目标项却删掉最后一条”的视觉错误(本质是绑定的属性错位了)

修复方案

直接使用当前行的menuItem对象绑定ngModel,而不是依赖索引。因为menuItem本身就是menu.snacks数组中的元素,绑定它的属性可以避免索引错位问题:

修改后的模板代码:

<table mat-table [dataSource]="menuTableSource" #menuTable>
  <ng-container matColumnDef="fruit">
    <th mat-header-cell *matHeaderCellDef> Fruit </th>
    <td mat-cell *matCellDef="let menuItem">
      <mat-select [(ngModel)]="menuItem.fruitId" name="fruitId" #fruitId="ngModel">
        <mat-option *ngFor="let fruit of fruits" [value]="fruit.id"> {{ fruit.name }} </mat-option>
      </mat-select>
    </td>
  </ng-container>
  <ng-container matColumnDef="drink">
    <th mat-header-cell *matHeaderCellDef> Drink </th>
    <td mat-cell *matCellDef="let menuItem">
      <mat-select [(ngModel)]="menuItem.drinkId" name="drinkId" required>
        <mat-option *ngFor="let drink of drinks" [value]="drink.id"> {{drink.name}} </mat-option>
      </mat-select>
    </td>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="menuTableColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: menuTableColumns;"></tr>
</table>

额外说明

你的删除逻辑本身是没问题的:标记条目为deleted,然后过滤更新数据源并调用renderRows()。修改模板绑定后,就能正确对应到每个条目的属性,删除操作会精准作用于目标项,表格也会正确渲染过滤后的内容。

内容的提问来源于stack exchange,提问作者HenrikM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:35:46