2017-11-05 9 views
1

emailEmail Confirmかどうかを確認する検証が必要でした。このため は私がangular4:valueChanges observableを使用したカスタム 'equals'検証

import { AbstractControl, ValidationErrors, FormGroup } from '@angular/forms'; 

export function ValidateEqual(equals: string) { 
    return (control: AbstractControl): ValidationErrors | null => { 

    const equalsField = control.root.get(equals) 
    if (equalsField) { 

     equalsField.valueChanges.subscribe(value => { 
     console.log('observable fired', value); 
     // control.updateValueAndValidity({ onlySelf: true , emitEvent: false }); 
     }); 
     if (control.value !== equalsField.value) { 
     return { equals: true }; 
     } 
    } 
    return null; 
    } 
} 

のように見え、私のフォームは、だから私はValidateEqual()で引数としてで平等をチェックするために、フィールドを渡しています

this.loginForm = this.fb.group({ 
    password: [ '', [ 
    Validators.required, 
    ] ], 
    email: [ '', [ 
    Validators.required, 
    Validators.email, 
    ] ], 
    emailConfirm: [ '', [ 
    Validators.required, 
    Validators.email, 
    ValidateEqual('email'), 
    ] ] 
}); 

のように見えるカスタム検証を作成しました。それはうまく動作します。

次のシナリオが失敗した:

1)

メール:

確認メールを[email protected]

[email protected] *今すぐメールを確認すると、そのエラーを示しますそれは `Email 'と等しくありません。正しい。

2)

*今私はconfirm emailフィールドに一致するようにemailフィールドを変更します。

メール:

確認メールを[email protected]:それはどんな変化を認識していないので、confirm emailフィールド上のエラーが消えない*

[email protected]

私が持っている問題は、私は再検証するcontrolフィールドを持つように等号フィールド上で観察valueChangesを使用しようとしていますが、私はcontrol.updateValueAndValidity()を有効にした場合、それは各キー入力に指数関数的に加入していると、ブラウザがクラッシュするということであり、 。 ITはemail confirmフィールドに再検証するように通知するので、ほとんど動作します...ほとんど。

誰かが一度だけ購読し、再度購読しないでcontrolフィールドの再検証を行う方法を知っていますか?ここで

+0

これをチェックしてください:https://stackoverflow.com/questions/43487413/password-および確認パスワードフィールド検証2応答形式 – Alex

答えて

1

を追加するには、検証同等クラスの書き込みに 同じかそうでない問題があることですに置かれたValidatorFnは、明らかに、FormControlの値が変更されたときにのみチェックされます。私たちが望むのは、emailまたはemailConfirmのいずれかが変更されたときにチェックすることです。これを実現するには、FormControlの代わりにFormGroupを検証する必要があります。 ValidatorFnAbstractControlを受け取るので、私たちの関数はFormGroup、FormControlまたはFormArrayを受け取ることができます。

static matches(form: AbstractControl){ 
    return form.get('email').value == form.get('emailConfirm').value ? null : {equals: true}; 
} 

今、あなたのコンポーネントでは、あなたはまだ、このバリデータを追加する必要があり、それは少し違う:

this.form = this.fb.group({...}, {validator: CustomValidator.matches}); 

あなたは私たちがバリを取る引数としてそれを第2の目的を渡すことができます見ることができるように

:あなたのテンプレートで

FormGroup全体のためにフォーム全体ではなく、個々のFormControlの等号エラーを持っているかどうかをチェックします
3

は、二つの電子メールをチェックする方法です。このコード

export class emailValidation { 
    static matchEmail(AC: AbstractControl){ 
     let email=AC.get('email').value; 
     let emailConfirm=AC.get('emailConfirm').value; 
     if(email!=emailConfirm){ 
      console.log(false); 
     } 
    } 
} 

およびコンポーネントでは、このコードに

this.loginForm = this.fb.group({ 
    password: [ '', [ 
    Validators.required, 
    ] ], 
    email: [ '', [ 
    Validators.required, 
    Validators.email, 
    ] ], 
    emailConfirm: [ '', [ 
    Validators.required, 
    Validators.email, 
    ] ] 
}, 
{ 
    validator:passwordValidation.matchPassword 
    }); 
0

良い例をお寄せいただきありがとうございます。フォーム上でこれを行うのは理にかなっており、他のコントロールに反応する方法や応答する方法がわからないため、formControlではなくです。

私はEqualバリデータで比較されるフィールドを制御できるように微調整を行いました。 私は私のフィールドの下のどこか別のエラーメッセージを追加する必要がないように私も(私はマテリアルデザインマット・フォーム・フィールドを使用)field2コントロールにエラーを設定します。

interface IEmailMatchFields { 
    field1: string; 
    field2: string; 
} 
export class EmailMatch { 

    fields: IEmailMatchFields; 
    constructor(fields: IEmailMatchFields) { 
    this.fields = fields; 
    } 
    emailMatches(form: AbstractControl) { 

    if (this.fields) { 
     if (form.get(this.fields.field1).value == form.get(this.fields.field2).value) { 
     form.get(this.fields.field2).setErrors({ 'emailNotEq': false }); 
     form.get(this.fields.field2).updateValueAndValidity({ onlySelf: true }); 
     return null; 
     } else { 
     form.get(this.fields.field2).setErrors({ 'emailNotEq': true }); 
     return { emailNotEq: true }; 
     } 
    } 
    } 
} 

export class MyComponent implements OnInit { 
    emailMatch: EmailMatch; 
    registerForm: FormGroup; 

    constructor(
    private fb: FormBuilder 
) { 
    this.emailMatch = new EmailMatch({ field1: 'email', field2: 'emailConfirm' }); 
    } 

    ngOnInit(): void { 
    this.registerForm = this.fb.group({ 
     password: [ '', [ 
     Validators.required, 
     ] ], 
     email: [ '', [ 
     Validators.required, 
     Validators.email, 
     ] ], 
     emailConfirm: [ '', [ 
     Validators.required, 
     Validators.email, 
     ] ] 
    }, { 
     validator: this.emailMatch.emailMatches.bind(this.emailMatch) 
    }); 
    } 
} 

私は推測する代わりに、 field1field2 2つのフォームコントロールの参照を渡すこともできますが、formcontrolをフォームグループなどに追加する必要があります。 キーの送信はうまく動作すると思います。

2

githubでngx-validationをご覧ください。 小さなオープンソースのlibです。直接使用することもできますし、フォークすることもできます。

関連する問題