Angular 反应式表单自定义验证不适用于模糊,角度7
我在验证Angular 7中模糊的确认传递字段时遇到问题。在我的例子中,我构建了多个自定义验证器,这些验证器在控件变为“脏”后工作,还有一个遵循Pascal Prechts教程的指令,它在只触及字段时对模糊有效,但我想要一个纯反应式解决方案,Pascal需要添加到HTML中 问题示例:单击进入firstName字段,立即单击tab或单击out-内置必需的验证器激发。 单击进入confirmPass字段,立即单击或签出;自定义验证器不会启动(即使控制台日志也不会显示)。如果你要在制表符或点击前输入任何一个字符,那么我所做的每个版本都可以工作 我尝试过用多个静态方法构建一个验证器类。控制所有使用的方法(“控制器”),该方法检查传入的字段名并适当重定向。这直接返回了一个错误映射或空值,而不是函数,当然不起作用 接下来我尝试了Pascal Prechts教程;这是一个指令——我必须在HTML中输入equalValidator——我不想这样做 最后,我尝试了Angular建议函数和StackOverflow上的另一个函数,它们都返回一个函数;它本身返回错误映射或null FormGroupAngular 反应式表单自定义验证不适用于模糊,角度7,angular,typescript,Angular,Typescript,我在验证Angular 7中模糊的确认传递字段时遇到问题。在我的例子中,我构建了多个自定义验证器,这些验证器在控件变为“脏”后工作,还有一个遵循Pascal Prechts教程的指令,它在只触及字段时对模糊有效,但我想要一个纯反应式解决方案,Pascal需要添加到HTML中 问题示例:单击进入firstName字段,立即单击tab或单击out-内置必需的验证器激发。 单击进入confirmPass字段,立即单击或签出;自定义验证器不会启动(即使控制台日志也不会显示)。如果你要在制表符或点击前输入
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' });
}
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);
}
}
最后,我做了两次最新的尝试,第一次是官方推荐的角度文档的变体
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_验证器有关,但……即使是这样,我也不确定如何做到这一点。Angular在创建
FormControl
时第一次运行验证器,然后每次FormControl
中的值都会发生变化。当你仅仅聚焦和模糊输入时,没有再验证
对于required
字段,它的工作原理如下:当您通过FormBuilder
创建FormControl
时,它将得到验证,并且从一开始就存在错误。它只是不可见,因为尚未触摸输入。对于matchingInputsValidator
而言,错误不存在,因为两个字段在开始时是相同的,因此当您触摸输入时,不会显示错误
只要password
发生更改,您需要自己触发对confirmPass
表单控件的验证。一个很好的地方是valueChanges
订阅password
表单控件
this.password.valueChanges.subscribe(() => this.confirmPass.updateValueAndValidity());
你会发现更新的stackblitz演示。你能创建一个简单的stackblitz.com演示来演示这个问题吗?我会去看看我能做些什么是的,这里有一个stackblitz的问题:注意,在这一个上,验证在minLength、maxLength和email的blur之前启动……我不太担心这一点,因为它在原来的项目上工作得很好。然而,在这个项目中也存在同样的问题-对于原始confirmPass,在blur上不会进行验证,任何帮助都非常值得赞赏。在这种情况下,如何验证日期字段在blur上是否有效。