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

Angular使用NGRX渲染表格时避免全表重绘,仅渲染变更行的解决方案

解决Angular表格修改行数据时整体重绘闪烁的问题

问题场景

我正在使用NgRx从远程API加载数据到数组,并将其渲染到传统HTML表格中。但遇到一个问题:当修改某一行数据(比如点击按钮修改数组中的某一行)时,整个表格会重新渲染,出现闪烁现象。我想知道是否可以配置Angular,让它只重新渲染数组中发生变更的行?

我的初始化代码:

ngOnInit() { 
  this.store 
    .select( 
      createSelector( 
        (state: AppState) => state.userProperties, 
        (propObject: UserProperties) => propObject 
      ) 
    ) 
    .pipe(takeUntil(this.destroyed$)) 
    .subscribe(({properties, total }) => { 
      this.propertyList = properties; 
      this.totalFound = total; 
    })

表格渲染代码:

<tbody> 
  <ng-container *ngFor="let row of propertyList"> 
    <tr> 
      <td> 
      </td> 
      <td class="limited">{{ row.id }}</td> 
      <td class="limited">{{ categoryLabels[row.category] | _: trans.lang }}</td> 
      <td class="limited">{{ contractLabels[row.contract_type] | _: trans.lang }}</td> 
      <td class="limited">{{ row.price }}</td> 
      <td class="limited">{{ row.city }}</td> 
      <td class="limited"> 
      </td> 
      <td> 
        <div class="table-actions"> 
          <button (click)="editProperty(row.id)" class="button button-icon"> 
            <edit-icon></edit-icon> 
          </button> 
          <button *ngIf="row.deleted === 0" (click)="archiveProperty(row.id)" title="Delete this property" class="button button-icon"> 
            <img src="/assets/images/icons/delete-red.svg" /> 
          </button> 
          <button (click)="toggleExpand(row.id)" class="button button-icon btn-expand"> 
            <expand-icon [expanded]="expandedElements[row.id]"></expand-icon> 
          </button> 
        </div> 
      </td> 
    </tr> 
  </ng-container>

解决方案(感谢@Dmytro Demyanenko)

要实现仅重新渲染变更的行,你需要给*ngFor指令添加trackBy属性:

修改后的ngFor代码:

<ng-container *ngFor="let row of propertyList; trackBy: trackByFn">

然后在组件类中定义trackByFn函数:

trackByFn(index, row) { 
  return JSON.stringify(row); 
}

原理说明

Angular的*ngFor默认会通过对象引用或者索引来追踪元素是否需要重绘。当你从NgRx获取新的properties数组时,即使只有一行数据变化,整个数组的引用可能发生了改变,导致Angular重新渲染所有行。

而trackBy函数的作用是告诉Angular如何识别哪些元素是相同的:只有当trackBy函数返回的值与上次不同时,Angular才会重新渲染对应的行。这里我们返回row的JSON字符串,当行内任何数据发生变更时,这个字符串就会改变,从而触发该行的重新渲染,其他未变更的行则保持原样,避免了整个表格的闪烁问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:07:29