2016-02-18 8 views
45

См. Это question относительно Сравнение полей в валидаторе с угловым2. К сожалению, Angular 2 немного изменился, так что решение, похоже, больше не работает. Вот мой код:Угловая форма 2, подтверждающая пароль повторения

import {IonicApp,Page,NavController,NavParams} from 'ionic/ionic' 
import {Component} from 'angular2/core' 
import {FORM_PROVIDERS, FormBuilder, Validators} from 'angular2/common' 
import {ControlMessages} from '../../components/control-messages' 
import {ValidationService} from '../../services/validation-service' 

@Page({ 
    templateUrl: 'build/pages/account/register.html', 
    directives: [ControlMessages] 
}) 
export class RegisterPage { 

    constructor(nav:NavController,private builder: FormBuilder) { 
    this.nav = nav 
    this.registerForm = this.builder.group({ 
     'name' : ['', Validators.required], 
     'email' : ['',Validators.compose([Validators.required, ValidationService.emailValidator])], 
     'password' : ['',Validators.required], 
     'repeat' : ['',this.customValidator] 
     } 
    )   
    } 

    register() {  
    alert(this.registerForm.value.password) 
    } 

    private customValidator(control) {   
    //console.log(this.registerForm.value.password) 
    //return {isEqual: control.value === this.registerForm.value.password} 
    return true 
    } 
} 

Моего HTML:

<ion-content class="account"> 
    <ion-list padding> 
    <form [ngFormModel]='registerForm' (submit)='register()'> 
     <div class="centered"> 
     <img class="logo" src="img/logo.png" alt=""> 
     </div> 
     <div class="spacer" style="height: 20px;"></div> 

     <ion-input> 
     <ion-label floating>Name</ion-label> 
     <input type="text" ngControl='name' id='name'> 
     <control-messages control="name"></control-messages>    
     </ion-input> 

     <ion-input> 
     <ion-label floating>Email</ion-label> 
     <input type="email" ngControl='email' id='email'> 
     <control-messages control="email"></control-messages>    
     </ion-input> 

     <ion-input> 
     <ion-label floating>Password</ion-label> 
     <input type="password" ngControl='password' id='password' value=""> 
     <control-messages control="password"></control-messages>   
     </ion-input> 

     <ion-input> 
     <ion-label floating>Confirm Password</ion-label> 
     <input type="password" ngControl='repeat' id='repeat'> 
     <control-messages control="repeat"></control-messages>     
     </ion-input> 

     <button class="calm" full type='submit' [disabled]='!registerForm.valid'>Register</button> 

     <ion-item style="background-color:transparent;border:none;"> 
     <button class="text-button" clear item-right (click)="gotoLogin()">Have an account already, Login</button> 
     </ion-item> 
    </form> 
    </ion-list> 

</ion-content> 

Но, к сожалению, я не могу получить доступ к значению 'пароль' в моей проверяющей функции. Если я раскомментировать console.log (this.registerForm.value.password), то я получил следующее сообщение об ошибке:

EXCEPTION: TypeError: Cannot read property 'value' of undefined

Любая идея? Благодарю.

ответ

55

Я вижу несколько проблем в вашем коде. Вы пытаетесь использовать ключевое слово this в функции проверки подлинности, и это не соответствует экземпляру компонента. Это связано с тем, что вы ссылаетесь на функцию при ее установке как функции валидатора.

Кроме того, значение, связанное с элементом управления, может быть достигнуто в собственности value.

То есть, я думаю, что правильный способ проверить свои два поля вместе, чтобы создать группу и связать валидатор в нем:

this.registerForm = this.builder.group({ 
    'name' : ['', Validators.required], 
    'email' : ['',Validators.compose([Validators.required, 
         ValidationService.emailValidator])], 
    'passwords': fb.group({ 
    password: ['', Validators.required], 
    repeat: ['', Validators.required] 
    }, {validator: this.areEqual}) 
});  

Таким образом, вы будете иметь доступ ко всем элементам управления группы и не только один и больше не нужно использовать ключевое слово this ... Доступ к этому можно получить, используя свойство группового управления controls. Последний (не один) напрямую предоставляется при срабатывании проверки. Например:

areEqual(group: ControlGroup) { 
    var valid = false; 

    for (name in group.controls) { 
    var val = group.controls[name].value 

    (...) 
    } 

    if (valid) { 
    return null; 
    } 

    return { 
    areEqual: true 
    }; 
} 

Смотрите эту Anwer для получения более подробной информации:

Редактировать

Чтобы отобразить сообщение об ошибке, вы можете просто использовать следующее:

<span *ngIf="!registerForm.passwords.valid" class="help-block text-danger"> 
    <div *ngIf="registerForm.passwords?.errors?.areEqual"> 
    The two passwords aren't the same 
    </div> 
</span> 
+0

Это работает. Благодарю. Но нужно спросить, как назначить ошибку для поля «повторить пароль». Я не могу получить доступ к ngModel внутри функции проверки подлинности, могу ли я? –

+0

В другом слове areEqual возвращает ошибку для формы не для ввода (ngControl). Как я могу вернуть ошибку для ngControl? –

+0

Добро пожаловать! Что касается вашего вопроса, вы можете просто использовать элемент 'registerForm.passwords' ... Я обновил свой ответ –

2

Кроме того, как угловая 2 rc4 с формами 0.2.0 Разметкой и атрибутом выкрикивая имя группы, используемое для охвата сгруппированных входов необходимо для предотвращения ошибок

<div formGroupName="passwords">group input fields here... </div> 
2

Сохранить пароль в переменную экземпляра.

password = new FormControl('', [Validators.required]); 

Тогда используйте его в своей группе форматов.

 this.registrationForm = this.fb.group({ 
     'email': ['', [ 
      Validators.required, 
      NGValidators.isEmail, 
     ] 
     ], 
     'password': this.password, 
     'password2': ['', [Validators.required, this.passwordMatch]] 
    }); 

Таким образом, функция выглядит следующим образом.

private passwordMatch() { 
     let that = this; 
     return (c: FormControl) => 
     { 
      return (c.value == that.password.value) ? null : {'passwordMatch': {valid: false}}; 
     } 
    } 

Я знаю, что это не лучшее решение, но его работа!

3

Используя эту библиотеку ng2-validation-manager вы можете легко сделать это:

this.form = new ValidationManager({ 
    'password' : 'required|rangeLength:8,50', 
    'repassword' : 'required|equalTo:password' 
}); 
+2

вы можете определить свою собственную проверку с помощью ng2-validation manager, например, тот, который может отправить rquest на сервер и проверить, зарегистрировано ли электронное письмо –

+0

прямо сейчас нет, у вас нет такой возможности для расширения валидатора, но я планирую это в будущем –

+1

@sabri благодарит за создание валидаторов, подобных валидаторам laravel. Я думал создать свои собственные валидаторы, но сегодня я увидел то, что хотел. ;) Надеюсь, это будет способствовать этому: D – PaladiN

0

Я просто хочу, чтобы опубликовать свое решение:

this.authorizationSettings = formBuilder.group({ 
     currentPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])], 
     newPassword: [null, Validators.compose([Validators.required, Validators.minLength(8)])], 
     repeatNewPassword: [null] 
    }); 
    this.authorizationSettings.controls.newPassword.valueChanges.subscribe(data => { 
     if (data) { 
     data = data.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); 
     } 
     this.authorizationSettings.controls.repeatNewPassword 
     .clearValidators(); 
     this.authorizationSettings.controls.repeatNewPassword 
     .setValidators(Validators.compose([Validators.required, Validators.pattern(data)])); 
    }); 

Нам нужно создать форму группы, а затем подписаться на первый новый затем добавьте подтверждение для повторного поля.

11

нашел намного более простое решение. Не уверен, если это правильный способ сделать это, но это работает для меня

<!-- PASSWORD --> 
<ion-item [ngClass]="{'has-error': !signupForm.controls.password.valid && signupForm.controls.password.dirty}"> 
    <ion-input formControlName="password" type="password" placeholder="{{ 'SIGNUP.PASSWORD' | translate }}" [(ngModel)]="registerCredentials.password"></ion-input> 
</ion-item> 

<!-- VERIFY PASSWORD --> 
<ion-item [ngClass]="{'has-error': !signupForm.controls.verify.valid && signupForm.controls.verify.dirty}"> 
     <ion-input formControlName="verify" [(ngModel)]="registerCredentials.verify" type="password" pattern="{{registerCredentials.password}}" placeholder="{{ 'SIGNUP.VERIFY' | translate }}"> </ion-input> 
</ion-item> 

См

pattern="{{registerCredentials.password}}" 
+0

Это, безусловно, самое простое решение здесь. – mikeo

+1

Будьте осторожны, сбой пароля не будет, если пароль содержит специальные символы, например * (звезда) –

+0

Решение решетки. Короткие, простые, не нужны внешние библиотеки, а не создание групп входов. Вам просто нужно удалить компоненты «ionic», потому что они не имеют никакого отношения к решению –

14

Я реализовал валидатор пользовательских паролей соответствия для углового 4.

Помимо проверки если два значения совпадают, он также подписывается на изменения от другого элемента управления и повторно проверяет, когда обновляется один из двух элементов управления. Не стесняйтесь использовать его как ссылку для своей собственной реализации или просто скопируйте ее напрямую.

Вот ссылка на решение:https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30.


И здесь я обеспечиваю копию кода:

матч-другой-validator.ts

import {FormControl} from '@angular/forms'; 


export function matchOtherValidator (otherControlName: string) { 

    let thisControl: FormControl; 
    let otherControl: FormControl; 

    return function matchOtherValidate (control: FormControl) { 

    if (!control.parent) { 
     return null; 
    } 

    // Initializing the validator. 
    if (!thisControl) { 
     thisControl = control; 
     otherControl = control.parent.get(otherControlName) as FormControl; 
     if (!otherControl) { 
     throw new Error('matchOtherValidator(): other control is not found in parent group'); 
     } 
     otherControl.valueChanges.subscribe(() => { 
     thisControl.updateValueAndValidity(); 
     }); 
    } 

    if (!otherControl) { 
     return null; 
    } 

    if (otherControl.value !== thisControl.value) { 
     return { 
     matchOther: true 
     }; 
    } 

    return null; 

    } 

} 

Использование

Вот как вы можете использовать его с реактивным формы:

private constructForm() { 
    this.form = this.formBuilder.group({ 
    email: ['', [ 
     Validators.required, 
     Validators.email 
    ]], 
    password: ['', Validators.required], 
    repeatPassword: ['', [ 
     Validators.required, 
     matchOtherValidator('password') 
    ]] 
    }); 
} 

Более актуальные валидаторы можно найти здесь: moebius-mlm/ng-validators.

+0

Как работает утечка памяти, поскольку эта статическая функция хранит экземпляр 'thisControl' и' otherControl'? Сохранена ли эта память бесконечно? – kbpontius

+1

@kbpontius Я не эксперт в сборке мусора JavaScript, но, как я вижу, когда вы вызываете 'matchOtherValidator()', он создает закрытие, прикрепленное к возвращенной функции matchOtherValidate(). Таким образом, когда форма уничтожается, она должна освободить ссылку функции matchOtherValidate() 'и закрытие вместе с ней. Пожалуйста, поправьте меня, если я ошибаюсь. –

+0

Я бы сговорился, хотя мой опыт, вероятно, меньше, чем ваш. Вообще говоря, по моему опыту с другими языками, это будет так, как это работает. Благодарю. – kbpontius

2

Ну, я искал ответ на эту тему, и все они были слишком большими для моей лености, поэтому я сделал это так. Я думаю, что это хорошо работает.

I used the ngModel to bind password and repeatPassword input and then i have shown or hide the div with password comparison message with [hidden] attribute in angular 2.

<label for="usr">Password</label> 
    <input placeholder="12345" id="password" type="text" class="form-control" 
    [(ngModel)]="password"> 
    <label for="usr">Repeat pasword</label> 
    <input placeholder="12345" type="text" class="form-control" 
    [(ngModel)]="repeatPassword"> 
    <div [hidden]="password == repeatPassword">Passwords do not match!</div> 
1

Вот мой путь, используя угловые валидатор

КОМПОНЕНТ:

import { UserModel } from '../../settings/users/user.model'; 
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; 
import { FormRequestModel } from '../Shared/form.model'; 
import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'app-add-user', 
    templateUrl: './add-user.component.html', 
    styleUrls: ['./add-user.component.scss'] 
}) 
export class AddUserComponent implements OnInit { 

    passwordsForm: FormGroup; 
    user: UserModel; 
    constructor(private fb: FormBuilder) { } 

    ngOnInit() { 

     this.passwordsForm = this.fb.group({ 
     inputPassword: ['', Validators.compose([Validators.required, Validators.minLength(6), Validators.maxLength(50)])], 
     inputPasswordAgain: [''] 
     }); 

    } 
} 

HTML:

<form class="form-horizontal" [formGroup]="passwordsForm" novalidate> 
    <div class="form-group"> 
    <br/> 
    <label for="inputPassword" class="col-sm-2 control-label">Password</label> 
    <div class="col-sm-10"> 
     <input type="password" formControlName="inputPassword" class="form-control" id="inputPassword" placeholder="Password"> 
    </div> 
    </div> 
    <div class="alert alert-danger" *ngIf="!passwordsForm.controls['inputPassword'].valid && passwordsForm.controls['inputPassword'].touched">Password must contain at least 6 characters!!</div> 


    <div class="form-group"> 
    <br/> 
    <label for="inputPasswordAgain" class="col-sm-2 control-label">Password again</label> 
    <div class="col-sm-10"> 
     <input type="password" formControlName="inputPasswordAgain" class="form-control" id="inputPasswordAgain" placeholder="Password again"> 
    </div> 
    </div> 

    <!-- Show div warning element if both inputs does not match the validation rules below --> 

    <div class="alert alert-danger" *ngIf="passwordsForm.controls['inputPasswordAgain'].touched 
    && passwordsForm.controls['inputPasswordAgain'].value !== passwordsForm.controls['inputPassword'].value"> 
    Both passwords must be equal!</div> 
1

Я нашел решение, которое заставило меня счастливее, насколько непротиворечивость кода ошибка handli нг:

первый: Создайте пользовательский класс проверки со статическим методом, который делает проверки достоверности

Этот метод должен иметь параметр AbstractControl который угловой впрыскивает

Обратите внимание, что вы будете передавать это в контроле ConfirmPassword, поэтому вам нужно позвонить родителям, чтобы добраться до FormGroup. Оттуда вы вызываете formGroup.get ('myControl') и получаете элементы управления для пароля и подтверждаете, как вы их назвали, когда вы создали группу форм.

import {AbstractControl} from '@angular/forms'; 

export class PasswordValidation { 

    static MatchPassword(AC: AbstractControl) { 
     const formGroup = AC.parent; 
     if (formGroup) { 
      const passwordControl = formGroup.get('Password'); // to get value in input tag 
      const confirmPasswordControl = formGroup.get('Confirm'); // to get value in input tag 

      if (passwordControl && confirmPasswordControl) { 
       const password = passwordControl.value; 
       const confirmPassword = confirmPasswordControl.value; 
       if (password !== confirmPassword) { 
        return { matchPassword: true }; 
       } else { 
        return null; 
       } 
      } 
     } 

     return null; 
    } 
} 

второй: Используй клиент валидатор так же, как вы используете углам главного

this.registerForm = this.fb.group({ // <-- the parent FormGroup 
       Email: ['', Validators.required ], 
       Username: ['', Validators.required ], 
       FirstName: ['', Validators.required ], 
       Password: ['', 
           [ 
            Validators.required, 
            Validators.minLength(6) 
           ] 
          ], 
       Confirm: ['', 
           [ 
            Validators.required, 
            PasswordValidation.MatchPassword 
           ] 
          ] 
       }); 

Угловой затем добавить «matchPassword»: верно вашей Confirm ошибки управления точно так, как он хотел бы добавить «требуется» истинного, когда отсутствует значение

0

Только начиная с угловым и я нашел это решение, не знаю, если это хорошая практика ты:

// Custom password confirmation validation 
    static matchFieldValidator(fieldToMatch:string) : ValidatorFn { 
    return (control : AbstractControl) : { [key: string]: any;} => { 
     let confirmField = control.root.get(fieldToMatch); 

     return (confirmField && control.value !== confirmField.value) ? {match:false} : null; 
    } 
    } 

Таким образом, вы можете просто сделать что-то вроде этого при настройке правил проверки

this.registrationForm = fb.group({ 
    ... 
    password1 : ['', [Validators.minLength(3)]], 
    // remember to replace RegisterComponent with YOUR class name 
    password2 : ['', [RegisterComponent.matchFieldValidator('password1')]], 
    }); 
6

Угловая 4.3.3 решение!

Вы можете сделать это с помощью: [formGroup], formGroupNameformControlName, в HTML и new FormGroup, new FormControl и пользовательские areEqual метод в TS

reg.component.html

<div [formGroup]="userFormPassword"> 
    <div> 
    <input formControlName="current_password" type="password" placeholder="Current Password"> 
    </div> 

    <div formGroupName="passwords"> 
    <input formControlName="new_password" type="password" placeholder="New Password"> 
    </div> 

    <div formGroupName="passwords"> 
    <input formControlName="repeat_new_password" type="password" class="form-control" placeholder="Repeat New Password"> 
    <div class="input-error" *ngIf=" 
      userFormPassword.controls['passwords'].errors && 
      userFormPassword.controls['passwords'].errors.areEqual && 
      userFormPassword.controls['passwords'].controls.repeat_new_password.touched && 
      userFormPassword.controls['passwords'].controls.new_password.touched 
     ">PASSWORDS do not match 
    </div> 
    </div> 
</div> 

reg.component .ts

export class HomeHeaderSettingsModalComponent implements OnInit { 
    userFormPassword: FormGroup; 
    // ... 

    static areEqual(c: AbstractControl): ValidationErrors | null { 
    const keys: string[] = Object.keys(c.value); 
    for (const i in keys) { 
     if (i !== '0' && c.value[ keys[ +i - 1 ] ] !== c.value[ keys[ i ] ]) { 
     return { areEqual: true }; 
     } 
    } 
    } 

    ngOnInit() { 
    this.userFormPassword = new FormGroup({ 
     'current_password': new FormControl(this.user.current_password, [ 
     Validators.required, 
     ]), 
     'passwords': new FormGroup({ 
     'new_password': new FormControl(this.user.new_password, [ 
      Validators.required 
     ]), 
     'repeat_new_password': new FormControl(this.user.repeat_new_password, [ 
      Validators.required 
     ]) 
     }, HomeHeaderSettingsModalComponent.areEqual) 
    }); 
    } 
} 

Результат: result

2

Резюме

  • Trigger проверки каждый раз, когда значение других изменений управления.
  • Отказаться, чтобы избежать утечек памяти
  • возвращение {match: true} позволит нам проверить, является ли данный элемент управления имеет ошибку, используя myControl.hasError('match')

Реализация

import { AbstractControl, ValidatorFn } from '@angular/forms'; 
import { Subscription } from 'rxjs/Subscription'; 

export function matchOtherValidator(otherControlName: string): ValidatorFn { 
    return (control: AbstractControl): { [key: string]: any } => { 
     const otherControl: AbstractControl = control.root.get(otherControlName); 

     if (otherControl) { 
      const subscription: Subscription = otherControl 
       .valueChanges 
       .subscribe(() => { 
        control.updateValueAndValidity(); 
        subscription.unsubscribe(); 
       }); 
     } 

     return (otherControl && control.value !== otherControl.value) ? {match: true} : null; 
    }; 
} 

Пример

this.registerForm = formBuilder.group({ 
      email: ['', [ 
       Validators.required, Validators.email 
      ]], 
      password: ['', [ 
       Validators.required, Validators.minLength(8) 
      ]], 
      confirmPassword: ['', [ 
       Validators.required, matchOtherValidator('password') 
      ]] 
     }); 
2

Мое решение для углового 4.3.4, который не требует дополнительного FormGroup:

  • регистров пользовательского валидатора для repeatedPassword проверки, если пароли совпадают
  • подписаться обработчик на password.valueChanges при создании формы, и называют .updateValueAndValidity() method на repeatedPassword

Вот код:

form: FormGroup 
passwordFieldName = 'password' 
repeatedPasswordFieldName = 'repeatedPassword' 

createForm() { 
    this.form = this.formBuilder.group({ 
    login: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255), Validators.email]], 
    [passwordFieldName]: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(255)]], 
    [repeatedPasswordFieldName]: ['', [Validators.required, this.samePassword]] 
    }); 

    this.form 
    .get(passwordFieldName) 
    .valueChanges.subscribe(() => { 
     this.form 
     .get(repeatedPasswordFieldName).updateValueAndValidity(); 
    }) 
} 

samePassword(control: FormControl) { 
    if (!control || !control.parent) { 
    return null; 
    } 
    if (control.value !== control.parent.get(passwordFieldName).value) { 
    return {'passwordMismatch': true} 
    } 
    return null; 
} 
0

Это самый простой способ, которым я следую. Я удалил код, который не имеет значения.

Я думаю, это поможет вам.

auth.component.ts, auth.component.html, auth.component.css

import { Component, OnInit, EventEmitter, Input, Output ,Directive, forwardRef, Attribute,OnChanges, SimpleChanges} from '@angular/core'; 
 
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from '@angular/forms'; 
 
import { ActivatedRoute, Router } from '@angular/router'; 
 

 
import { RegisterUser } from '../shared/models'; 
 

 
@Component({ 
 
    moduleId: module.id, 
 
    selector: 'auth-page', 
 
    styleUrls: ['./auth.component.css'], 
 
    templateUrl: './auth.component.html' 
 
}) 
 

 
export class AuthComponent implements OnInit { 
 
    userRegisterModel: RegisterUser = new RegisterUser(); 
 
    
 
    constructor(private route: ActivatedRoute, private router: Router) { } 
 
    
 
    ngOnInit() { 
 
    this.userRegisterModel.LoginSource = 'M';//Manual,Facebook,Google 
 
} 
 

 
    userRegister() { 
 
    console.log(this.userRegisterModel); 
 
    } 
 

 
}
.validation 
 
{ 
 
    margin:0; 
 
    padding-top: 1px; 
 
    padding-bottom: 0px; 
 
} 
 
.validation .message 
 
{ 
 
    font-size: 10px; 
 
    color: #de1a16; 
 
}
  <form (ngSubmit)="userRegister()" #authRegisterForm="ngForm" novalidate> 
 

 
          <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <label>First Name:</label> 
 
           <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.firstName" name="firstName" 
 
            #firstName="ngModel" placeholder="Your first name"> 
 
           <div style="display: flex;">&nbsp; 
 
            <div [hidden]="firstName.valid || firstName.pristine" class="validation"> 
 
             <div [hidden]="!firstName.hasError('required')" class="message">Name is required</div> 
 
             <div [hidden]="!firstName.hasError('pattern')" class="message">Only alphabets allowed</div> 
 
            </div> 
 
           </div> 
 
          </div> 
 

 
          <div class="col-md-6 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <label>Last Name:</label> 
 

 
           <input type="text" class="form-control" required pattern="[a-zA-Z][a-zA-Z ]+" [(ngModel)]="userRegisterModel.lastName" name="lastName" 
 
            #lastName="ngModel" placeholder="Your last name"> 
 

 

 
           <div style="display: flex;">&nbsp; 
 
            <div [hidden]="lastName.valid || lastName.pristine" class="validation"> 
 
             <div [hidden]="!lastName.hasError('required')" class="message">Name is required</div> 
 
             <div [hidden]="!lastName.hasError('pattern')" class="message">Only alphabets allowed</div> 
 
            </div> 
 
           </div> 
 
          </div> 
 

 
          <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <label>Email:</label> 
 

 
           <input type="text" class="form-control" required [(ngModel)]="userRegisterModel.email" name="email" pattern="^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$" 
 
            #email="ngModel" placeholder="Your email"> 
 

 
           <div style="display: flex;">&nbsp; 
 
            <div [hidden]="email.valid || email.pristine" class="validation"> 
 
             <div [hidden]="!email.hasError('required')" class="message">Email is required</div> 
 
             <div [hidden]="!email.hasError('pattern')" class="message">Email format should be 
 
              <small> 
 
               <b>[email protected]</b> 
 
              </small> 
 
             </div> 
 
            </div> 
 
           </div> 
 
          </div> 
 

 
          <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <label>Password:</label> 
 
           <input type="password" class="form-control" required [(ngModel)]="userRegisterModel.password" name="password" #password="ngModel" 
 
            minlength="6" placeholder="Your strong password" > 
 

 
           <div style="display: flex;">&nbsp; 
 
            <div [hidden]="password.valid || password.pristine" class="validation"> 
 
             <div [hidden]="!password.hasError('minlength')" class="message">Password should be 6digit</div> 
 
             <div [hidden]="!password.hasError('required')" class="message">Password is required</div> 
 
            </div> 
 
           </div> 
 
          </div> 
 

 
          <div class="col-md-12 form-group" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <label>Confirm Password:</label> 
 
           <input type="password" class="form-control" required validateEqual="password" [(ngModel)]="userRegisterModel.confirmPassword" 
 
            name="confirmPassword" #confirmPassword="ngModel" placeholder="Confirm your password"> 
 

 
           <div style="display: flex;">&nbsp; 
 
            <div [hidden]="confirmPassword.valid || confirmPassword.pristine" class="validation"> 
 
             <div class="message">Passwords did not match</div> 
 
            </div> 
 
           </div> 
 
          </div> 
 

 
       
 
          
 

 
          <div class="col-md-12 form-group text-right" style="padding-right: 5px;padding-left: 0px;margin-bottom: 0;"> 
 
           <button type="submit" class="btn btn-primary" [disabled]="!authRegisterForm.form.valid"> 
 
            Submit form 
 
            <i class="icon-arrow-right14 position-right"></i> 
 
           </button> 
 
          </div> 
 
         </form>

registerUser.mocel.ts

export class RegisterUser { 
 
    FirstName : number; 
 
    LastName : string; 
 
    Email: string; 
 
    Password : string; 
 
    } 

password.match.directive.ts

import { Directive, forwardRef, Attribute } from '@angular/core'; 
 
import { NG_VALIDATORS,Validator,Validators,AbstractControl,ValidatorFn } from '@angular/forms'; 
 

 
@Directive({ 
 
    selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]', 
 
    providers: [ 
 
     { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true } 
 
    ] 
 
}) 
 
export class EqualValidator implements Validator { 
 
    constructor(@Attribute('validateEqual') public validateEqual: string) {} 
 

 
    validate(c: AbstractControl): { [key: string]: any } { 
 
     // self value (e.g. retype password) 
 
     let v = c.value; 
 

 
     // control value (e.g. password) 
 
     let e = c.root.get(this.validateEqual); 
 

 
     // value not equal 
 
     if (e && v !== e.value) return { 
 
      validateEqual: false 
 
     } 
 
     return null; 
 
    } 
 
}

app.module.ts

import { ModuleWithProviders, NgModule } from '@angular/core'; 
 
import { BrowserModule } from '@angular/platform-browser'; 
 
import { RouterModule } from '@angular/router'; 
 

 
//import { AppRoutingModule } from './app-routing.module'; 
 
//import { AppComponent } from './app.component'; 
 

 
//shared components 
 
import { EqualValidator} from './shared/password.match.directive'; 
 

 
@NgModule({ 
 
    declarations: [ 
 
    // AppComponent, 
 
    //FooterComponent, 
 
    // HeaderComponent, 
 
    // LoginComponent, 
 
    // LayoutComponent, 
 
    // AuthComponent, 
 
    // UserExistComponent, 
 
    // HomeComponent, 
 
    EqualValidator 
 
    ], 
 
    imports: [ 
 
    // BrowserModule,  
 
    // AppRoutingModule, 
 
    // SharedModule 
 
    ], 
 
    providers: [ 
 
    // ApiService, 
 
    // AuthGuard, 
 
    //JwtService, 
 
    // UserService, 
 
    // HomeAuthResolver, 
 
    // NoAuthGuard, 
 
    // SharedService 
 
    ], 
 
    bootstrap: [AppComponent] 
 
}) 
 
export class AppModule { }

0

Я не думаю, что нам нужен специальный валидатор для сопоставления паролей, чего можно легко достичь, используя formname.controls['controlName'].value.

<input type="password" class="form-control" formControlName="password"> 
<div class="alert alert-danger" *ngIf="!userForm.controls['password'].valid && userForm.controls['password'].touched"> 
    Enter valid password between 7 and 14 characters. 
</div> 
<input type="password" class="form-control" formControlName="confPassword"> 
<div *ngIf="userForm.controls['confPassword'].touched"> 
    <div class="alert alert-danger" *ngIf="userForm.controls['confPassword'].value != userForm.controls['password'].value"> 
     Password do not match 
    </div> 
</div> 

В fileName.component.ts контроль формы объявлен как:

'password':[null, Validators.compose([Validators.required, Validators.minLength(7), Validators.maxLength(14))], 
    'confPassword':[null, Validators.required] 
1

Если вы хотите создать директиву и использовать его затем see this

Вот полный код директивы

import { Directive, Attribute } from '@angular/core'; 
import { Validator, NG_VALIDATORS } from '@angular/forms'; 

@Directive({ 
    selector: '[advs-compare]', 
    providers: [{provide: NG_VALIDATORS, useExisting: CompareDirective, multi: true}] 
}) 
export class CompareDirective implements Validator { 

    constructor(@Attribute('advs-compare') public comparer: string){} 

    validate(c: Control): {[key: string]: any} { 
    let e = c.root.get(this.comparer); 
    if(e && c.value !== e.value){ 
     return {"compare": true}; 
    } 
    return null; 
    } 
} 

Для получения дополнительной информации, как его использовать, см. http://www.advancesharp.com/blog/1226/angular-5-email-compare-password-validation-different-ways

0

Отвечая на вопрос Чжоу Хао, который поднял вопрос о дебатах, я думаю, что это то, что вы искали, потому что это случилось со мной так же, как вы, он сказал, что переменная не определена и разрешает ее так:

static comparePassword(control) { 
    try { 
     control.parent.value.password; 
     if (control.parent.value.password == control.value) { 
     return null; 
     } else { 
      return { 'invalidValue': true }; 
     } 
    } catch (e) { 
     e.message; 
    } 
} 
Смежные вопросы