Angular 反应式表单 - 在值更改时显示/隐藏表单字段后执行验证

Angular Reactive Forms - Perform Validation After Form Fields Shown / Hidden on Value Changes

我正在使用具有各种必填字段的反应式表单进行验证。某些字段具有条件验证,只有在满足条件时才应进行检查。 (即如果您对上述问题的回答是肯定的,请说明原因)

在 HTML 中最终看起来像这样:

<input type="text" [required]="did_you_answer_yes_to_the_previous_question" />

这样,除非满足条件,否则反应形式不会验证该字段。

然后我检查 valueChanges 上的表单有效性,如下所示:

    this.form.valueChanges
        .pipe(
            concatMap((updatedForm: any) => {
                if (this.form.dirty) {                      
                    this.service.udpateFormIsValid(this.form.valid);
                    this.form.markAsPristine();
                }

                return of(updatedForm);
            })
        )
        .subscribe((updatedForm: any) => {  });

但是,验证发生在之前 angular 绑定更新导致误报和漏报。

我可以通过在 valueChanges observable 之后添加一个 .debounceTime(250) 来轻松修复它以缓解竞争条件,但是添加手动延迟似乎是一种反模式。

是否有更好的方法来确保我们在每次表单更新时都执行检查,但在 angular 更新了布尔条件绑定之后执行检查?

FormControl 有一个 statusChanges Observable 你可以 subscribe to.

因此代码可能如下所示:

        this.form.statusChanges
            .pipe(
                distinctUntilChanged()) // to reduce the noise
            .subscribe(() => {
                this.service.udpateFormIsValid(this.form.valid);
        });

您可以使用验证器来检查表单的有效性,即:

this.myForm = this.formBuilder.group({
      value1: ["", [Validators.maxLength(40)]], 
// etc...
});

然后您可以使用 statusChanges 订阅来检查表单是否有效。如果您想对这些值执行其他操作,您可以在执行操作时订阅 valueChanges。 为了避免 Observable 竞争,你只需要使用 RXJS 组合 observables:

combineLatest(this.myForm.valueChanges,this.myForm.statusChanges)
  .subscribe(([values, status])=>{
  // Do whatever you want with those values here
});

这样你就不需要做一些奇怪的事情,比如为其中一个调用添加延迟。