Angular响应式表单复选框required校验touched属性未定义问题咨询
报错原因
你在HTML模板中直接使用的suitColors未在TS类中声明为公开成员属性,读取不存在的属性返回undefined,调用undefined的touched属性就触发了该报错。同时还存在两个影响校验生效的隐藏问题:
- FormArray自带的
Validators.required仅校验对象是否为null/undefined,空数组会被判定为合法,不符合「至少选中一项」的校验需求 - 复选框操作不会自动标记FormArray为
touched状态,用户操作后不会主动触发错误提示
修复方案
1. 调整TS代码
在你的TS类中补充以下逻辑:
// 类内部首先声明form变量 public heroCreateForm: FormGroup; // 新增getter,给模板暴露suitColors对应的FormArray实例 get suitColors(): FormArray { return this.heroCreateForm.get('suitColors') as FormArray; } fromInit() { this.heroCreateForm = this.formBuilder.group({ // 替换原有的required校验为自定义长度校验 suitColors: new FormArray([], [ (control: AbstractControl) => { const arr = control as FormArray; return arr.length > 0 ? null : { required: true }; } ]), }); } onCheckChange(event) { const formArray: FormArray = this.suitColors; if (event.target.checked) { formArray.push(new FormControl(event.target.value)); } else { formArray.controls.forEach((ctrl: FormControl, i: number) => { if (ctrl.value === event.target.value) { formArray.removeAt(i); } }); } // 操作后标记为已触碰,触发校验提示 formArray.markAsTouched(); } invalidSuitColorsMessage() { if (this.suitColors.errors?.required) { return "You must choose the hero's suit colors"; } return ''; }
2. HTML代码无需额外修改
原来的模板中suitColors.touched和suitColors.invalid现在可以正常读取,校验逻辑会按预期生效:未选中任何选项时显示错误提示,提交按钮禁用;选中至少一个选项后提示消失,提交按钮恢复可用。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

