【问题标题】:UpdateValueAndValidity does not update the form valueUpdateValueAndValidity 不更新表单值
【发布时间】:2023-01-19 02:24:25
【问题描述】:

我已经在“模糊”(ngOnInit)上设置了我的表单的updateOn:

    this.formStepper = this._fb.group({
      steps: this._fb.array([
        this._fb.group({
          email: [
            this.formDataMail.dataValue,
            {
              updateOn: 'blur',
              validators: [Validators.required, Validators.email],
            },
          ],
        }),
        new FormGroup({}),
      ]),
    });

要手动验证我的输入 (ngAfterViewInit):

    fromEvent(this.emailInput.nativeElement, 'keyup')
      .pipe(
        filter(Boolean),
        debounceTime(600),
        distinctUntilChanged(),
        tap((_) => {
          this.formArray.at(0).get('email').updateValueAndValidity();
        })
      )
      .subscribe();

这应该根据我的验证器更新表单值并显示错误,但在我模糊之前我的表单值将保持为空。

    this.formArray
      .at(0)
      .valueChanges.pipe(
        takeUntil(this._onDestroy$),
        tap((changes: string ) => {
          // changes value is synchronized with blur action even if I call updateValueAndValidity function
        })
      )
      .subscribe();

为什么 updateValueAndValidity 不更新提到的值?

非常感谢你

作为一种解决方法,我尝试手动更新值并将表单标记为脏以在第一个模糊操作之前显示错误消息

    fromEvent(this.emailInput.nativeElement, 'keyup')
      .pipe(
        filter(Boolean),
        debounceTime(600),
        distinctUntilChanged(),
        tap((_) => {
          this.formArray
            .at(0)
            .get('email')
            .setValue(this.emailInput.nativeElement.value);
          this.formArray.at(0).get('email').markAsDirty();
          this.formArray.at(0).get('email').updateValueAndValidity();
        })
      )
      .subscribe();

【问题讨论】:

  • 也许我遗漏了一些东西,您已经将表单配置为在模糊时更新,但是您对为什么它只在您模糊输入时才更新感到困惑?为什么不使用定期更新策略?您已经通过在每次击键时运行验证来模拟正常的更新策略。你需要调用markAsDirty()的原因是它模糊了输入,然后值到达表单控件。
  • 这个想法是在用户停止书写或取消输入焦点后获取错误消息。我们不希望在用户尚未完成电子邮件输入时收到错误消息。我没有模拟正常更新,因为我放了一个 debounceTime

标签: angular typescript forms input materials


【解决方案1】:

我认为这种方法太复杂了。我提出以下解决方案。

1.) 移除updateOn: 'blur'

    this.formStepper = this._fb.group({
      steps: this._fb.array([
        this._fb.group({
          email: [
            this.formDataMail.dataValue,
            {
              validators: [Validators.required, Validators.email],
            },
          ],
        }),
        new FormGroup({}),
      ]),
    });

2.) 设置触摸输入时显示的错误(意思是模糊):

    <mat-error *ngIf="formArray.at(0).get('email').hasError('email') && !formArray.at(0).get('email').hasError('required')">
      Please enter a valid email address
    </mat-error>
    <mat-error *ngIf="formArray.at(0).get('email').hasError('required')">
      Email is <strong>required</strong>
    </mat-error>

3.) 订阅输入的变化并在 600 毫秒的去抖时间后将输入标记为已触摸:

    this.formArray.at(0).get('email').valueChanges.pipe(debounceTime(600)).subscribe(() => {
      this.formArray.at(0).get('email').markAsTouched();
    });

StackBlitz here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多