【发布时间】:2019-05-20 14:39:28
【问题描述】:
我在验证 Angular 7 中的确认传递字段 onBlur 时遇到问题。在我的情况下,我构建了多个自定义验证器,这些验证器在控件被设置为“脏”后工作,以及遵循 Pascal Prechts 教程的指令仅在字段被触摸时工作 onBlur,但我想要一个纯反应式解决方案,Pascal 需要添加到 HTML。
问题示例:点击进入 firstName 字段,立即选项卡或点击退出 - 内置必需的验证器触发。 点击进入confirmPass字段,立即点击或跳出;自定义验证器不会触发(甚至控制台日志也没有显示)。如果您要在跳格或单击之前键入任何单个字符,但是我制作的每个版本都可以工作。
我尝试使用多个静态方法构建验证器类。控制所有使用的一种方法('director'),该方法检查传入的字段名并适当地重定向。这直接返回了错误映射或空值而不是函数,当然没有用。
接下来我尝试了 Pascal Prechts 教程; https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html 用作指令 - 但是我必须在 HTML 中输入 equalValidator - 我不想这样做。
最后我尝试了 Angular 建议的函数和我在 StackOverflow 上找到的另一个函数,它们都返回一个函数;它本身返回错误映射或 null。
表单组
ngOnInit() {
this.regForm = this.fb.group({
firstName: ["", [Validators.required, Validators.minLength(2), Validators.maxLength(30)]],
lastName: ["", [Validators.required, Validators.minLength(2), Validators.maxLength(30)]],
email: ["", [Validators.required, Validators.email]],
password: ["", [Validators.required, Validators.minLength(8), Validators.maxLength(55)]],
confirmPass: ["", matchingInputsValidator],
}, { updateOn: 'blur' });
this.lgnForm = this.fb.group({
lgnEmail: ["", [Validators.required, Validators.email]],
lgnPass: ["", Validators.required]
}, { updateOn: 'blur' });
}
适用于Blur的Pascals解决方案,但仅作为指令
function validateEqualFactory(compare: string) : ValidatorFn {
return (c: FormControl) => {
// value of confirm password field
let v = c.value;
// value of compared field - in this case 'password'
let e = c.root.get(compare);
// Ternary operator -> return null if equal or error map if not equal/password does not exist
return (e && v === e.value) ? null : { misMatch: true };
};
}
@Directive({
selector: '[validateEqual][formControl],[validateEqual][formControlName]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
validator: ValidatorFn;
constructor() {
this.validator = validateEqualFactory("password");
}
validate(c: FormControl) {
return this.validator(c);
}
}
最后是我最近做的两个尝试,第一个是 Angular 文档官方推荐的变体
export function confirmPassVal(): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} | null => {
console.log("Making it here 1", control);
const passCtrl = control.root.get('password');
console.log("Making it here 2: ", passCtrl);
return (passCtrl && passCtrl.value === control.value) ? null : {"misMatch" : true };
}
}
export const matchingInputsValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
let pass;
control.root.get('password') ? pass = control.root.get('password').value : pass = null;
let confirmPass = control.value;
return pass === confirmPass ? null : { misMatch: true };
}
我希望我的函数在字段被触摸和/或脏时运行,但它目前仅在字段脏时运行。在一个理想的世界中,我希望能够使用我自己的自定义函数扩展 Validators 或 NG_VALIDATORS 类,这完全来自 FormBuilder 声明。在这一点上,我认为这与多提供者有关,并且扩展了 NG_VALIDATORS 但是....即使是这种情况,我也不知道该怎么做。
【问题讨论】:
-
你能创建一个简单的 stackblitz.com 演示来演示这个问题吗?
-
我去看看我能做什么耶
-
这是一个问题的堆栈闪电:stackblitz.com/edit/angular-crnns8 请注意,在这个问题上,验证在 minLength、maxLength 和电子邮件模糊之前触发......我不太担心这个,因为它在原始项目上运行良好。然而,同样的问题在这个项目中被复制了——对于原始的 confirmPass,验证不会发生 onBlur,非常感谢任何帮助
标签: angular typescript