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

Angular ngModel绑定输入框每输入一个字符就失焦如何解决

问题根因

*ngFor默认通过对象引用身份追踪列表项变更,你的contact.adress是字符串原始值数组,每次输入触发ngModel更新数组对应索引的字符串时,原始值的引用会发生改变,Angular会判定该列表项被整体替换,直接销毁旧DOM、重新渲染新节点,原本聚焦的输入框被销毁,自然就出现每输入一个字符就失焦的现象。

修复方法
  • 方法一:添加trackBy追踪函数(改动最小,推荐)
    通过trackBy指定按索引追踪列表项,只要索引不变就不重建对应DOM:

    1. 在组件TS文件中添加trackBy方法:
      trackByIndex(index: number): number {
        return index;
      }
      
    2. 修改模板中*ngFor的配置,追加trackBy规则:
      <div *ngFor="let phoneAddress of contact.adress; let i = index; trackBy: trackByIndex">
          <label for="adress">Adress</label>
          {{phoneAddress}}
          <input type="text" [(ngModel)]="contact.adress[i]" [ngModelOptions]="{standalone: true}">
          <button (click)="removeAddress(i)">-</button>
          <button (click)="addAddress()">+</button>
      </div>
      
      原有新增、删除地址的逻辑不需要调整即可正常使用。
  • 方法二:调整数组存储结构
    把原始字符串数组改为对象数组,由于对象的引用不会随着内部属性值变化而改变,*ngFor不会误判列表项被替换:

    1. 调整数据结构,将contact.adress的类型从string[]改为{content: string}[],新增地址时推入空对象:
      addAddress() {
        this.contact.adress.push({content: ""});
      }
      
      removeAddress(ind: number): void {
        this.contact.adress.splice(ind, 1);
      }
      
    2. 调整模板中的绑定目标为对象属性:
      <div *ngFor="let phoneAddress of contact.adress; let i = index">
          <label for="adress">Adress</label>
          {{phoneAddress.content}}
          <input type="text" [(ngModel)]="contact.adress[i].content" [ngModelOptions]="{standalone: true}">
          <button (click)="removeAddress(i)">-</button>
          <button (click)="addAddress()">+</button>
      </div>
      
      该方案不需要额外加trackBy,但需要调整上下游涉及地址数据的处理逻辑,适合还在开发初期、数据结构未定型的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:45:32