【问题标题】:Angular async validator stuck角异步验证器卡住
【发布时间】:2021-07-12 23:31:17
【问题描述】:

我有一个很大的响应式表单,它显示在两个选项卡上(每个选项卡都由 *ngIf 隐藏/显示)。我通过 Inputs() 将必要的 FormGroups / Arrays 传递给这些选项卡。在第二个选项卡上,有一个基于 FormArray 构建的项目列表,其中一些 FormControls 具有如下异步验证器:

static ibanValidator(service: ValidationService) {
    return (control: AbstractControl) => {
        if (!control.value) {
            return of(null);
        }

        return control.valueChanges.pipe(
            debounceTime(500),
            distinctUntilChanged(),
            take(1),
            switchMap(v => {
                return service.validateIBAN(v)
            }),
            map((result: ValidationStatus) => {
                let e = null;
                if (result !== ValidationStatus.OK) {
                    e = {};
                    e[result.toLowerCase()] = 'IBAN'
                }
                return e;
            })
        );
    }
}

当我停留在第二个选项卡上时一切正常(当我更改字段值时,验证器进行异步调用并且状态变为 -> PENDING -> VALID。 但是当我回到第一个选项卡时,然后在视图创建角度调用: _updateTreeValidity -> 并且对于每个导致异步验证器被调用的字段 updateValueAndValidity 并且我在具有异步验证器的字段上获得 PENDING 状态,因为控制没有改变 (_pendingChange = 假)。 如何正确处理?难道我做错了什么?我应该在单独的表单上构建每个选项卡吗?

感谢您的帮助!

【问题讨论】:

    标签: angular validation asynchronous


    【解决方案1】:

    无需分开表格。而且它与异步验证器无关。

    我认为原因是切换到第一个选项卡时,您只从.html文件中删除了第二个表单元素,但您没有更新.ts文件中的Fromgroup。因此,每次您对表单进行更改时,都会调用第二个表单组验证器。

    看看下面的简化代码。

    new FormGroup({
      firstFormGroup: new FormGroup(''),
      secondFormGroup: new FormGroup('', SomeValidator), // Remove this form control whenever you want to remove form tags from the thml page.
    });
    

    【讨论】:

    • 我不更新 FormGroup 因为我不想更新,我将整个状态保存在其中。在我看来,这是一种最方便的方式,而不是每次用户更改选项卡时都更新表单并从状态变量设置其值,我更喜欢有一个大表单来存储状态但只显示它的一部分。是否可以让表单只检查实际更改的 FormControls 的状态?
    • 在这种情况下,您可能需要将表单分开并在需要时将它们组合起来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 2021-11-26
    相关资源
    最近更新 更多