Angular在ngOnInit加载下拉框数据后提交表单出现校验报错问题
问题产生原因
- 响应式表单中同时使用了
formControlName和[(ngModel)]两种绑定语法,Angular 6及以上版本已废弃该混用用法,会导致表单控件状态与绑定变量状态不同步:表单校验读取的是响应式控件自身存储的value,你给selectedCompanyRole赋值的操作没有同步到表单控件,校验时会判定控件值为空,触发报错。 - 你通过
push方法原地修改selectedCompanyRole数组,不会触发ngModel的变更检测,即便保留双向绑定语法,这种赋值方式也无法将值同步到关联的表单控件。
可行解决方案
- 方案1(推荐):完全遵循响应式表单规范,移除ngModel相关逻辑
首先删除HTML代码中的[(ngModel)]="selectedCompanyRole"属性,同时修改onChange事件取值逻辑:
再修改TS中的赋值逻辑,直接操作表单控件赋值:<p-multiSelect [disabled]="isViewDisable" placeholder="Select an option" formControlName="companyRole" [options]="companyRoleOptions" optionLabel="name" optionValue="code" appMultiSelection (onChange)="getSelectedRole($event.value)" [ngClass]="{ 'is-invalid': submitted && p.companyRole.errors?.error }"></p-multiSelect>const roleCodes = this.companyRoleOptions.map(item => item.code); this.addNoticeForm.get('companyRole').setValue(roleCodes); this.getSelectedRole(roleCodes); - 方案2:保留ngModel变量,赋值后主动同步到表单控件
如果你需要保留selectedCompanyRole变量做其他逻辑处理,在完成数组赋值后主动将值同步给表单控件即可:this.companyRoleOptions.forEach((item) => this.selectedCompanyRole.push(item.code)); // 新增赋值逻辑,同步变量值到响应式表单控件 this.addNoticeForm.get('companyRole').setValue([...this.selectedCompanyRole]); this.getSelectedRole(this.selectedCompanyRole); - 额外排查项:如果修改后仍有报错,检查自定义校验指令
appMultiSelection的逻辑,确认校验规则与多选控件返回的数组值类型、长度判断逻辑匹配。
内容的提问来源于stack exchange,提问作者Mohamed Abubakar
相关产品推荐
相关产品推荐

