2017-09-09 14 views
1

Je n'arrive pas à comprendre pourquoi mon validateur personnalisé est à un pas de la valeur du champ. Exemple: mon champ de saisie a la valeur 123 tapée un par un. Mais mon validateur a la valeur 12.Angular (4): validateur personnalisé dans un formulaire basé sur un modèle montre la valeur actuelle du champ derrière

Je ne peux pas comparer correctement les valeurs entre deux champs. Ce est le validateur dans une directive:

@Directive({ 
    selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]', 
    providers: [ 
    { 
     provide: NG_VALIDATORS, 
     useExisting: forwardRef(() => PasswordValidationDirective), 
     multi: true 
    } 
    ] 
}) 
export class PasswordValidationDirective implements Validator { 
    @Input('first') first: string; 
    @Input('second') second: string; 

    constructor() { 
    } 

    public validate(ac: AbstractControl): { [key: string]: any } { 
    console.log(ac.root); 
    return null; 
    } 
} 

C'est le code html du champ:

<md-input-container class="full-width"> 
    <input mdInput 
     type="password" 
     required 
     ngModel name="passwordConfirmation" 
     #passwordConfirmation="ngModel" 
     minlength="6" 
     maxlength="30" 
     pattern="(?=^.{6,30}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$" 
     validateEqual 
     first="password" 
     second="passwordConfirmation" 
     placeholder="{{'PASSWORD_RECOVERY.PASSWORD_CONFIRMATION' | translate}}"> 
    <md-error *ngIf="passwordConfirmation.touched && passwordConfirmation.invalid"> 
    <span *ngIf="passwordConfirmation.errors.required"> 
     {{'PASSWORD_RECOVERY.FIELD_REQUIRED' | translate}} 
    </span> 
    <span *ngIf="passwordConfirmation.errors.minlength || passwordConfirmation.errors.maxlength"> 
     {{'PASSWORD_RECOVERY.PASSWORD_LENGTH' | translate}} 
    </span> 
    <span *ngIf="passwordConfirmation.errors.pattern" class="p-md-error-multiline-div"> 
     {{'PASSWORD_RECOVERY.FOR_A_SECURE_PASSWORD' | translate}} 
    </span> 
    </md-error> 
</md-input-container> 

Répondre

0

a finalement réussi à trouver une solution! J'ai décidé d'aller avec NgModelGroup. Voici la directive:

@Directive({ 
    selector: '[validateEqual][ngModelGroup]', 
    providers: [ 
    { 
     provide: NG_VALIDATORS, 
     useExisting: forwardRef(() => PasswordValidationDirective), 
     multi: true 
    } 
    ] 
}) 
export class PasswordValidationDirective implements Validator { 
    @Input('password') public password: string; 
    @Input('confirmation') public confirmation: string; 

    public validate(fg: FormGroup): { [key: string]: any } { 
    const fieldOne = fg.value[this.password]; 
    const fieldTwo = fg.value[this.confirmation]; 

    if (!fieldOne || !fieldTwo || fieldOne === fieldTwo) { 
     return null; 
    } 

    return {valueEquals: false}; 

    } 
} 

Et voici le HTML:

<div ngModelGroup="passwordGroup" 
    #passwordGroup="ngModelGroup" 
    validateEqual 
    password="password" 
    confirmation="passwordConfirmation"> 
    <div class="row"> 
    <div class="col-xs-6"> 
     <md-input-container class="full-width"> 
     <input mdInput 
       type="password" 
       required 
       ngModel name="password" 
       #password="ngModel" 
       placeholder="{{'SIGNUP.PASSWORD' | translate}}"> 
     </md-input-container> 
    </div> 
    <div class="col-xs-6"> 
     <md-input-container class="full-width"> 
     <input mdInput 
       type="password" 
       required 
       ngModel name="passwordConfirmation" 
       #passwordConfirmation="ngModel" 
       placeholder="{{'SIGNUP.RETYPE_PASSWORD' | translate}}"> 
     </md-input-container> 
    </div> 
    </div> 
    <div class="row"> 
    <div class="col-xs-12"> 
     <md-error *ngIf="passwordGroup.errors"> 
     <span class="p-text-small-error">{{'SIGNUP.MATCH' | translate}}</span> 
     </md-error> 
    </div> 
    </div> 
</div> 

Les parties importantes ici sont la directive elle-même et les paramètres entrants, qui peut être modifié à votre goût.