Angular动态HTML表格添加新行时原有行数据显示空白问题
问题原因
核心是两个Angular模板的错误用法导致的渲染异常:
- 模板驱动表单下
name属性绑定错误
使用[(ngModel)]的模板驱动表单中,name是Angular用来唯一标识表单控件的核心字段,必须全局唯一且固定不变。你当前将name绑定到了输入框本身的输入值{{dynamic.firstName}}/{{dynamic.lastName}}/{{dynamic.emailAddress}},新增行触发表单重绘时,Angular无法通过动态变化的name正确匹配原有控件和对应的值,就会出现输入框显示为空、但实际数组里数据正常的情况。如果后续出现不同行输入值重复的问题,还会导致多个输入框值互相覆盖。 *ngFor无trackBy优化触发全量DOM重绘
默认*ngFor通过对象引用跟踪列表项,往数组push新元素时,Angular会销毁所有已有的行DOM,再重新创建全部行的DOM,放大了上面name属性的错误影响。
解决步骤
第一步:修正name属性绑定
用*ngFor的索引i拼接每个输入框的唯一固定name,修改HTML中三个输入框的代码即可:
<!-- First Name输入框 --> <input style="width:120px" name="firstName-{{i}}" [(ngModel)]="dynamic.firstName" type="text" /> <!-- Last Name输入框 --> <input style="width:120px" name="lastName-{{i}}" [(ngModel)]="dynamic.lastName" type="text" /> <!-- Email输入框 --> <input style="width:250px" name="email-{{i}}" [(ngModel)]="dynamic.emailAddress" type="email"/>
修改后每个输入框的name固定且全局唯一,不会随输入值变化,Angular可以正确匹配控件和对应的值。
第二步:添加trackBy优化渲染(可选,推荐)
在TS文件中添加trackBy函数,避免新增行时重绘所有已有行DOM:
trackByFn(index: number, item: any): number { return index; // 如果你的数据项有唯一业务id,也可以返回item.id,效果更好 }
再修改*ngFor代码:
<tr *ngFor="let dynamic of dynamicArray; let i = index; trackBy: trackByFn">
修改完成后测试新增行功能,原有行的输入值就可以正常显示了。
内容的提问来源于stack exchange,提问作者Ted Herrlich
相关产品推荐
相关产品推荐

