Angular表单验证中自定义校验器不生效怎么办?
我在用 Angular 做注册表单,想加个自定义校验器检查密码强度,但写了 validator 之后表单控件的 errors 一直是 null,根本没触发。明明已经 import 了,也加到 formControl 里了,咋回事?
这是我的校验器代码:
export function strongPasswordValidator(control: AbstractControl): ValidationErrors | null {
const value = control.value;
if (!value) return null;
const hasUpperCase = /[A-Z]/.test(value);
const hasLowerCase = /[a-z]/.test(value);
const hasNumber = /d/.test(value);
const isValid = hasUpperCase && hasLowerCase && hasNumber && value.length >= 8;
return isValid ? null : { weakPassword: true };
}
然后在组件里这样用的:password: ['', [Validators.required, strongPasswordValidator]],但控制台打印 this.form.get(‘password’)?.errors 始终是 null。
问题出在你的正则表达式这里:
/d/这个写法是在匹配字面字符 "d",而不是数字。你应该写成/d/(需要转义)。由于这个错误,
hasNumber几乎永远是 false(除非密码里恰好有个字母 d),导致你的验证逻辑实际上是这样的:等等,按这个逻辑你应该看到 errors 才对...但你说一直是 null。
我再看一下哈,你确定控制台打印的不是初始值 null?在你输入任何字符之前,校验器里这段代码会直接返回 null:
所以你需要在表单里先输入点东西,验证器才会真正跑起来。
修复后的代码:
排查步骤:
先确保你的表单控件确实有值,然后在输入后检查一下。可以在组件里这样调试:
如果输入了符合要求的密码(8位以上、有大写、有小写、有数字)后 errors 变成 null,那就说明验证通过了。如果输入了不符合要求的密码,errors 应该变成
{ weakPassword: true }。你先改一下正则,把
/d/改成/d/,试试看能不能解决。