我正在将旧版 Angular 应用程序 (v7?) 一直升级到最新版本 (v17)。
我有一个包含这三个 FormControl 的 FormGroup:
username
password
confirmPassword
有两个验证器:
在 Angular 文档中它指出
出于性能原因,Angular 仅在所有同步验证器都通过时才运行异步验证器。每项都必须在设置错误之前完成。
这似乎与 v7 的功能不同,因为即使存在同步错误,我的异步验证器也总是会触发。
我知道这通常是一件好事,但是因为我的密码和确认密码有一个同步验证器来检查它们是否匹配,所以用户必须输入他们想要使用的密码两次,然后才会被告知该密码无效,这这是一次奇怪的经历。
我在文档中看不到任何方法来更改特定表单、控件或验证器的此行为,因此我打算将其转换为值更改的去抖订阅,并在控件上手动设置错误,以便它将总是跑。但如果可以避免的话我宁愿不这样做 - 有谁知道这是否可以配置?
谢谢!
已经尝试过:
我不知道有什么方法可以完全满足您的要求,但我可以为您提供一个解决方案,您可以自己验证控件。
考虑一个将用户名作为输入的用户注册表单,就像您一样,我们希望使用一些服务器端验证。
我能做的就是订阅控件
valueChanges
并在异步管道中运行验证函数:
constructor() {
const control = this.userSignUpForm.controls.firstName;
control.valueChanges.pipe(
takeUntilDestroyed(),
distinctUntilChanged(),
debounceTime(1000),
filter((value): value is string => !!value),
switchMap(() => AppValidators.checkValidName()(control))
).subscribe({
next: validationErrors => {
if (validationErrors) control.setErrors(validationErrors);
}
})
}
我们过滤空值,然后在
switchMap
运算符内使用异步验证器。
在这个例子中,
AppValidators.checkValidName
是一个AsyncValidatorFn
,我直接在我的RxJS流中使用它,如果你的验证器已经编写好了,它会派上用场。
之后将留下一个
ValidationErrors
对象或 null
。
我还使用
takeUntilDestroy
运算符,当在注入上下文(如构造函数)中使用该运算符时,将保证在组件被销毁时清除订阅。