Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 反应式表单自定义验证不适用于模糊,角度7_Angular_Typescript - Fatal编程技术网

Angular 反应式表单自定义验证不适用于模糊,角度7

Angular 反应式表单自定义验证不适用于模糊,角度7,angular,typescript,Angular,Typescript,我在验证Angular 7中模糊的确认传递字段时遇到问题。在我的例子中,我构建了多个自定义验证器,这些验证器在控件变为“脏”后工作,还有一个遵循Pascal Prechts教程的指令,它在只触及字段时对模糊有效,但我想要一个纯反应式解决方案,Pascal需要添加到HTML中 问题示例:单击进入firstName字段,立即单击tab或单击out-内置必需的验证器激发。 单击进入confirmPass字段,立即单击或签出;自定义验证器不会启动(即使控制台日志也不会显示)。如果你要在制表符或点击前输入

我在验证Angular 7中模糊的确认传递字段时遇到问题。在我的例子中,我构建了多个自定义验证器,这些验证器在控件变为“脏”后工作,还有一个遵循Pascal Prechts教程的指令,它在只触及字段时对模糊有效,但我想要一个纯反应式解决方案,Pascal需要添加到HTML中

问题示例:单击进入firstName字段,立即单击tab或单击out-内置必需的验证器激发。 单击进入confirmPass字段,立即单击或签出;自定义验证器不会启动(即使控制台日志也不会显示)。如果你要在制表符或点击前输入任何一个字符,那么我所做的每个版本都可以工作

我尝试过用多个静态方法构建一个验证器类。控制所有使用的方法(“控制器”),该方法检查传入的字段名并适当重定向。这直接返回了一个错误映射或空值,而不是函数,当然不起作用

接下来我尝试了Pascal Prechts教程;这是一个指令——我必须在HTML中输入equalValidator——我不想这样做

最后,我尝试了Angular建议函数和StackOverflow上的另一个函数,它们都返回一个函数;它本身返回错误映射或null

FormGroup

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上是否有效。