Angular5中ngFor结合ngModel时输入框编辑失焦问题求助
解决Angular *ngFor循环中输入框失焦的问题
这个问题我之前开发Angular项目时也碰到过,其实根源在于Angular的变更检测机制!当你在输入框中修改hero.powers[i]的值时,数组里的元素发生了变化,默认情况下*ngFor会把整个列表项重新渲染一遍——原来的输入框被销毁,新的输入框被创建,这就导致了焦点丢失,得重新点击才能继续编辑。
下面给你两种可行的解决方案,优先推荐第一种:
方法一:使用trackBy函数(最优解)
这个方法不需要修改你的数据结构,还能提升列表渲染的性能,是官方推荐的做法。
- 首先在你的
hero.component.ts组件类中定义一个trackBy函数,用来告诉Angular如何跟踪列表项的身份:
trackByPowerIndex(index: number, power: string): number { return index; // 用索引作为跟踪标识 }
- 然后修改模板中的
*ngFor指令,加上trackBy绑定:
<li *ngFor="let power of hero.powers; let i = index; trackBy: trackByPowerIndex"> <input [(ngModel)]="hero.powers[i]"/> </li>
这样设置后,当数组元素变化时,Angular只会更新对应索引的列表项内容,而不会销毁重建整个输入框,焦点就能保持住了。
方法二:修改数据结构为对象数组(应急方案)
如果暂时不想加trackBy函数,也可以通过修改数据结构来解决。把原来的字符串数组改成包含属性的对象数组,因为对象的引用不会随属性值变化而改变,Angular会识别到列表项没有被替换,不会重新渲染。
- 在组件类中调整
hero.powers的结构:
// 示例初始化,根据你的实际数据调整 hero = { powers: [{ value: '飞行能力' }, { value: '超级速度' }] };
- 模板中修改双向绑定的目标为对象的属性:
<li *ngFor="let power of hero.powers; let i = index"> <input [(ngModel)]="power.value"/> </li>
不过这种方法需要调整你的数据结构,如果原有业务逻辑依赖字符串数组的话,可能需要额外处理,所以还是优先用第一种方法更稳妥。
内容的提问来源于stack exchange,提问作者iSebbeYT
相关产品推荐
相关产品推荐

