Angular 反应式表单,使用自定义验证器与 valueChanges 订阅进行跨领域验证

问题描述

我正在尝试为反应式表单实现跨字段验证,我知道这可以通过订阅 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 (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...