1. 如何解决ngFor时,每次修改input框的值都会失去焦点
<ng-container *ngFor="let item of itemList; index as i; trackBy: trackByFn">
<input [(ngModel)]="itemList[i]" name="item" />
</ng-container>
trackByFn(index, item) {
return index;
}
为什么能生效?
*ngFor通过对象标志来跟踪数组中的每一项。在数组发生改变时,会通过标志来避免重复渲染已经存在的元素。
如果数组中包含了基本类型(string,boolean,number),当input修改之后,绑定效果就会失效。
就像angular天然支持检测到对象a中属性b的变化,但是检测不到数组[a,a2,…]中的某一项的值改变。
所以当ngFor中的input框的值发生改变时,每次都会重新渲染input,导致失焦。
2. 往itemList中动态操作时,每次页面刷新都会清空input框中的内容,实际数据中又是有值的
解决方法: 排查是否使用form标签或者用form标签包裹[(ngModel)]或使用[ngModelOptions]=“{standalone: true}”
<!-- 正常使用 -->
<ng-container *ngFor="let item of itemList; index as i; trackBy: trackByFn">
<input [(ngModel)]="itemList[i]" />
</ng-container>
引入FormsModule后,ngForm指令创建一个FormGroup实例,并绑定到一个form表单上,用来做状态校验。每一个包含[(ngModel)]的input框,会创建一个FormControl并通过name属性添加到上述FormGroup实例中。
<!-- 错误使用 -->
<form #tempForm="form1">
<ng-container *ngFor="let item of itemList; index as i; trackBy: trackByFn">
<input [(ngModel)]="itemList[i]" name="item" />
</ng-container>
</form>
itemList的每一项都会往form1中挂一个名字为item的formFormControl。最终所有的input框共用一个formControl,所有的输入框通过一个control进行校验。存在校验异常,或者input被清空的问题。
<!-- 正常使用 -->
<ng-container *ngFor="let item of itemList; index as i; trackBy: trackByFn">
<form #tempForm="form2">
<input [(ngModel)]="itemList[i]" name="item" />
</form>
</ng-container>
itemList的每一项都会在单独的form2中挂一个名字为item的formFormControl。每个formControl互相不影响。
<!-- 正常使用 -->
<form>
<ng-container *ngFor="let item of itemList; index as i; trackBy: trackByFn">
<input [(ngModel)]="itemList[i]" [ngModelOptions]="{standalone: true}"/>
</ng-container>
</form>
使用[ngModelOptions]=“{standalone: true}”,表明当前的ngModel不需要在父FormGroup注册formControl。