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

Angular中二维数组渲染输入框按键后焦点异常跳转问题求助

Angular二维数字数组双向绑定焦点异常跳转的原因

场景复现

在Angular项目中定义了如下二维数字数组:

[
    [1,1,1,1],
    [1,1,1,1]
]

通过*ngFor指令循环生成输入控件:

<table>
    <tbody>
        <tr *ngFor="let d of myData">
            <td *ngFor="let factor of d; let i = index">
                <input type="number" [(ngModel)]="d[i]">
            </td>
        </tr>
    </tbody>
</table>

异常现象

  • 每次按下按键后,焦点会跳转到同行的下一个输入框;到行尾后焦点移出,无法跳转到下一行
  • 输入值时,同行后续输入框会显示前一个输入框的值,但数组对应元素的实际值并未改变
  • 将内部数组元素从number类型改为{ value: 1 }这类对象类型后,异常跳转现象完全消失

原因分析

核心问题出在Angular的*ngFor跟踪机制和变更检测逻辑上:

  1. *ngFor默认采用值跟踪,对于number这类原始数据类型,当你通过双向绑定修改数组元素值时,原数值会被替换为新数值——Angular会认为这个元素是一个全新的对象,因此会销毁原来的输入框DOM节点,重新创建一个新的输入框。
  2. DOM节点的销毁重建会打乱浏览器的焦点管理,导致焦点自动跳转到下一个输入框;同时由于DOM重建和数组更新的时序差,会出现后续输入框显示值异常的情况。
  3. 当使用对象类型时,我们修改的是对象内部的value属性,对象本身的引用并未改变——*ngFor会识别到这是同一个元素,不会触发DOM的销毁重建,因此焦点和双向绑定都能正常工作。

替代解决方案(无需修改数据结构)

如果不想将原始类型改为对象,可以给*ngFor添加trackBy函数,基于索引跟踪元素,避免DOM不必要的重建:

  1. 在组件类中定义跟踪函数:
trackByIndex(index: number): number {
  return index;
}
  1. 修改模板中的*ngFor指令:
<td *ngFor="let factor of d; let i = index; trackBy: trackByIndex">
  <input type="number" [(ngModel)]="d[i]">
</td>

内容的提问来源于stack exchange,提问作者Miro J.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 19:45:10