问题描述
我正在尝试为反应式表单实现跨字段验证,我知道这可以通过订阅 valueChanges(经过测试并有效)来完成,但我决定创建一个验证器函数工厂来实现它是一个好主意相反:
export function DependentrequiredFactory(dependentField:AbstractControl,value:any,errorMassage:string|null=null):
ValidatorFn {
return (control: AbstractControl): { [key: string]: string } | null => {
console.log('DependentrequiredValidator:');
if (dependentField?.value===value) {
if (control.value===null||control.value.length === 0)
{
return { 'required': errorMassage??'this is a required field' }
}
}
return null;
};
}
但是,在运行时将它与实际表单一起使用时,我收到错误 -
NG0100:ExpressionChangedAfterItHasBeenCheckedError:表达式有 检查后更改。以前的值:'假'。当前值: 'true'.. 详情请见 https://angular.io/errors/NG0100
即使对字段进行进一步更改,form.valid 也不会变回有效
字段:
get locationType():FormControl|null{return this.timeAndLocationDetailsFormGroup.get('locationType') as FormControl;};
get requestedLocation():FormControl|null{return this.timeAndLocationDetailsFormGroup.get('requestedLocation') as FormControl;};
形式:
this.timeAndLocationDetailsFormGroup=this._fb.group({
locationType:[this.eLocationTypes.CURRENT_LOCATION,[Validators.required]],requestedTime:[Date.Now(),requestedLocation:[]
});
this.form=this._fb.group({
timeAndLocationDetails:this.timeAndLocationDetailsFormGroup
});
this.requestedLocation?.setValidators(DependentrequiredFactory(this.locationType!,this.eLocationTypes.OTHER));//has to be done outside form building so it will recognize the field
html:
<div class="mt-2 mb-2">
<mat-radio-group aria-label="Select an option" formControlName="locationType">
<mat-radio-button [value]="eLocationTypes.CURRENT_LOCATION">Current Location</mat-radio-button>
<mat-radio-button [value]="eLocationTypes.OTHER">Other</mat-radio-button>
</mat-radio-group>
</div>
<mat-form-field class="w-100" *ngIf="locationType?.value===eLocationTypes.OTHER">
<mat-label>Address</mat-label>
<input matInput type="text" [formControl]="requestedLocation!">
<mat-error *ngIf="requestedLocation?.errors&&requestedLocation?.touched">
has errors
</mat-error>
</mat-form-field>
<mat-form-field class="w-100">
<mat-label>Requested Time</mat-label>
<input matInput type="text" [formControl]="requestedTime!">
<mat-error *ngIf="requestedTime?.errors">
has errors
</mat-error>
</mat-form-field>
<button type="submit" mat-raised-button color="primary" class="w-100 mb-2"
[disabled]="!form.valid">Done</button>
这种方法有什么问题? (我知道它以某种方式减少了角度变化检测周期,但不明白为什么它与任何其他验证器功能不同)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)