Angular 8中如何基于表单另一输入值对FormGroup输入项实现校验
问题解决方案
1. 解决模板语法报错
Angular 8的模板解析器不支持可选链操作符?.后跟方括号取值语法,你参考的是高版本Angular的文档示例,不适用于当前版本。提供两种兼容修改方案:
- 方案1:改用点语法取值
<div *ngIf="dialogForm.errors?.crossValid && dialogForm.dirty" class="form-validation-warning"> <span class="warning-label">* Required</span> </div>
- 方案2:用表单自带的
hasError方法(更推荐,兼容性更好)
<div *ngIf="dialogForm.hasError('crossValid') && dialogForm.dirty" class="form-validation-warning"> <span class="warning-label">* Required</span> </div>
2. 修正自定义交叉校验器逻辑
当前校验器存在两个核心问题:
- 变量名错误:代码中出现未定义的
attachment变量 - 校验逻辑完全不符合需求:现有逻辑是只要上传文件就报错,和要求的规则完全相反
修正后的校验器代码:
export const crossFormValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { const reasonForChange = control.get('reasonForChange'); const file = control.get('File'); // 核心校验逻辑:未选择文件 且 未填写Reason → 校验不通过 const noFile = !file?.value || (file.value instanceof FileList && file.value.length === 0); const noReason = !reasonForChange?.value || reasonForChange.value.trim() === ''; return noFile && noReason ? { crossValid: true } : null; };
同时修正表单初始化代码,删掉reasonForChange控件的固定必填校验(否则会固定要求填写Reason,和交叉校验规则冲突):
constructor(private fb: FormBuilder) { this.dialogForm = this.fb.group({ chooseStatus: [null, Validators.required], // 该控件如果仍需要必填就保留 reasonForChange: [null], File: [null], }, { validators: crossFormValidator }); }
3. 修正ngClass样式绑定逻辑
你之前的逻辑是判断File控件是否非法来给Reason输入框加样式,不符合需求。正确逻辑是:校验不通过且Reason为空时,给输入框加非法样式:
<textarea id="reasonForChange" formControlName="reasonForChange" name="reasonForChange" [ngClass]="{invalid: dialogForm.hasError('crossValid') && !dialogForm.get('reasonForChange').value}" ></textarea>
注意:请删掉代码里的[(ngModel)]="selectedReasonText",响应式表单和ngModel混用在Angular 8中会导致值同步异常,直接通过this.dialogForm.get('reasonForChange').value取值即可。
4. 补充文件控件值同步逻辑
Angular响应式表单默认不会自动同步type="file"输入框的值,你需要在onFileChange方法里手动更新File控件的值:
onFileChange(event: Event) { const input = event.target as HTMLInputElement; this.dialogForm.get('File').setValue(input.files); // 手动触发表单校验更新 this.dialogForm.updateValueAndValidity(); }
内容的提问来源于stack exchange,提问作者Rin and Len
相关产品推荐
相关产品推荐

