具有异步表单字段验证的Angular 2

时间:2016-07-21 16:16:02

标签: angular

我正在尝试使用同步和异步验证来验证字段。在异步验证结束之前字段更改时出现问题。如果在更改验证后返回错误(该字段无效),但仍有异步验证正在运行(来自之前的值),并且之后异步验证返回,该字段再次变为有效,但应保持无效。 / p>

Plunker

我创建了一个用于显示此事件的plunker:http://plnkr.co/edit/q0jttO

使用验证器创建FormGroup(使用新表单)的plunker代码是:

this.formGroup = formBuilder.group({
    id: [''],
    name: [
        '', 
        (c: AbstractControl) => (c.value != null && c.value.length >= 3) ? null : {
            key: 'name_minlength', 
            msg: 'The name must have at least 3 characters'
        }
    ],
    email: [
        '', 
        (c: AbstractControl) => {
            if (c.value != null && c.value.length !== 4) {
                console.log('sync - success -> ' + c.value);

                return null; // OK
            } else {
                console.log('sync - error -> ' + c.value);

                return {
                    key: 'email_4char', 
                    msg: 'The email must not have 4 characters'
                };
            }
        },
        (c: AbstractControl) => new Promise(
            resolve => {
                console.log('async started -> ' + c.value);

                setTimeout(() => {
                    if (c.value !== 'aaa') {
                        console.log('async ended - success -> ' + c.value);

                        resolve(null); //OK
                    } else {
                        console.log('async ended - error -> ' + c.value);

                        resolve({
                            key: 'email_aaa', 
                            msg: 'The email must be different than "aaa"'
                        });
                    }
                }, 2000)
            }
        )
    ]
});

我不知道这件事是我忘记做了什么,还是我做错了,或者它是否是角2的问题(毕竟,它还处于测试阶段)。

模拟步骤

我已经完成了模拟此问题的步骤,如果键入aaa,则验证会产生异步错误,如果键入aaaa,则会出现同步错误。

您可以在plunker中重现这些步骤(您可以在浏览器控制台中查看验证的日志):

  1. 在电子邮件字段中键入aa(该字段有效)。
  2. 然后键入另一个a并等待验证(异步 验证将显示错误。)
  3. 然后输入另一个a(成为aaaa)和同步验证 将显示错误(直到现在它还好,但等待)。
  4. 删除最后2 a以再次成为aa
  5. 在验证结束前输入1 a,然后输入另一个a
  6. 将显示来自aaaa验证的错误消息,但异步验证将结束,消息将消失。

    日志

    同步验证,其中电子邮件不得包含4个字符(仅用于示例目的),并且必须显示错误消息:

    1)显示错误(缓慢输入时控制台日志):

    sync - success -> aaa
    async started -> aaa
    async ended - error -> aaa
    sync - error -> aaaa
    

    2)显示错误,但在上一次异步调用返回成功后隐​​藏它(当键入更快时控制台日志):

    sync - success -> aaa
    async started -> aaa
    sync - error -> aaaa
    async ended - success -> aaaa
    

    不仅错误没有显示,而且该类也保持为ng-valid(应该无效,因为它没有显示错误)。

    如果我将异步验证器更改为仅返回有效(使用null解析),也会发生这种情况,因为发生的情况是从前一个值返回的异步更改了最后一个值类型的验证结果(这不应该& #39; t发生;只有与最后一个值相关的验证才应定义其有效性:

    resolve => {
        console.log('async started -> ' + c.value);
    
        setTimeout(() => {
            console.log('async ended -> ' + c.value);
            resolve(null); //OK
        }, 2000)
    }
    

    是否有办法让字段保持无效,即使在输入的最后一个值的验证错误后,前一个值的异步验证结束了?

0 个答案:

没有答案