我正在尝试使用同步和异步验证来验证字段。在异步验证结束之前字段更改时出现问题。如果在更改验证后返回错误(该字段无效),但仍有异步验证正在运行(来自之前的值),并且之后异步验证返回,该字段再次变为有效,但应保持无效。 / 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中重现这些步骤(您可以在浏览器控制台中查看验证的日志):
aa
(该字段有效)。a
并等待验证(异步
验证将显示错误。)a
(成为aaaa
)和同步验证
将显示错误(直到现在它还好,但等待)。a
以再次成为aa
。a
,然后输入另一个a
。 将显示来自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)
}
是否有办法让字段保持无效,即使在输入的最后一个值的验证错误后,前一个值的异步验证结束了?