【问题标题】:Angular form.statusChanges not working with dynamic form + asyncValidationAngular form.statusChanges 不适用于动态表单 + asyncValidation
【发布时间】:2019-11-05 16:01:16
【问题描述】:

当使用 asyncValidation 向反应式表单动态添加新的 FormControl 时,表单会从 PENDING 变为 VALID/INVALID,但不会触发 statusChanges。

我有一个动态修改的表单,之后我订阅了 statusChanges。我正在打印表单的状态,我可以检查状态是否发生了变化,但没有触发 stausChanges。

这是一个示例 https://stackblitz.com/edit/angular-pvebmb?file=src%2Fapp%2Fapp.component.ts

在此示例中,您可以检查是否订阅了 console.log 以获取 statusChanges。有一个按钮,当单击该按钮时,会添加一个新的 FormControl,它需要 1 秒才能完成异步验证。您可以检查,当您单击按钮时,表单的状态(打印在 html 中)从 PENDING 变为 INVALID,但没有打印与 statusChanges 相关的 console.log。

我希望每次表单的状态值更改时都会触发 statusChanges。

【问题讨论】:

  • 更改控件的状态,而不是表单的状态,你可以使用:this.form.get('simpleValue').statusChanges.subscribe((status) => console.log('STATUS has changed: ' + status),因为你把验证器放在了控件中
  • 但是不应该每次表单状态改变时触发statusChanges吗?在示例中,您可以在页面中看到 form.status 已更改。
  • 我删除了“simpleValue”表单控件,因为此示例不需要。

标签: angular


【解决方案1】:

它看起来像是设计完成的。它不会触发状态更改,因为它在初始化(或updateValueAndValidity 的第一次运行时)无效,并且如果您检查 FormControl 的代码,该事件将被阻止发出。你可以在这里查看: https://github.com/angular/angular/blob/8.2.13/packages/forms/src/model.ts#L1275

如您所见,emitEvent 是错误的。

这并不能真正解决您的问题,但至少可以解释为什么会这样。在您的示例中,如果您在按下控件后立即将该值设置为空值,您将获得该状态更改,因为那时updateValueAndValidityemitEvent 设置为true。因此,如果您真的希望 statusChanges 在初始化时触发,则 workAround 会将 formControl 的 setValue 设置为空。

【讨论】:

  • 非常感谢。我所做的是在添加后在添加的 formControl 中调用 updateValueAndValidity 并且正在工作。
【解决方案2】:

当用户没有输入任何内容并单击提交按钮时,我遇到了类似的问题,当消息组件依赖于侦听输入的 statusChanges 时,我的验证器不会触发错误消息。 (注意:也许我的验证不是异步验证)

我的解决方案是在单击提交按钮时调用以下函数,并且可以正常工作:

validateAllFields(formGroup: FormGroup) {
    Object.keys(formGroup.controls).forEach(field => {
        const control = formGroup.get(field);
        if (control instanceof FormControl) {
            control.markAsTouched({ onlySelf: true });
            control.updateValueAndValidity();
        }
    });
}

【讨论】:

    【解决方案3】:

    另一种解决方法是使用rxjs 运算符,如startWith 来触发可观察对象的初始值并将其存储在另一个可观察对象中,并使用该运算符而不是formGroup.statusChanges

    const formStatusChanges$ = formGroup.statusChanges.pipe(
      startWith(formGroup.status),
    );
    

    【讨论】:

    • 这不起作用。它正在发送初始状态。但是提交后还是没有触发
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2017-06-28
    • 2017-03-02
    相关资源
    最近更新 更多