Walidator Angular2, który opiera się na wielu polach formularzy


119

Czy jest możliwe utworzenie walidatora, który może używać wielu wartości do decydowania, czy moje pole jest prawidłowe?

np. jeśli preferowaną metodą kontaktu klienta jest e-mail, to pole e-mail powinno być wymagane.

Dzięki.


Zaktualizowano przykładowym kodem ...


    import {Component, View} from 'angular2/angular2';
    import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';

    @Component({
        selector: 'customer-basic',
        viewInjector: [FormBuilder]
    })
    @View({
        templateUrl: 'app/components/customerBasic/customerBasic.html',
        directives: [formDirectives]
    })
    export class CustomerBasic {
        customerForm: ControlGroup;

        constructor(builder: FormBuilder) {
            this.customerForm = builder.group({
                firstname: [''],
                lastname: [''],
                validateZip: ['yes'],
                zipcode: ['', this.zipCodeValidator] 
                // I only want to validate using the function below if the validateZip control is set to 'yes'
            });
        }

        zipCodeValidator(control) {
            if (!control.value.match(/\d\d\d\d\d(-\d\d\d\d)?/)) {
                return { invalidZipCode: true };
            }
        }

    }

Tak. A jeśli pokażesz nam swój kod, możemy dodać konkretną odpowiedź.
michelem

Dodałem podstawowy przykład. W przykładowym kodzie, jak mogę sprawdzić poprawność kodu pocztowego tylko wtedy, gdy poprzednia kontrolka validateZip zawiera „tak”?
Simon

Simon, dlaczego nie promowania w odpowiedzi na swoje pytanie?
superjos

6
Ok, aby zaoszczędzić przyszłym odwiedzającym to pytanie wiele frustracji, bardzo polecam użycie tego pakietu NPM: npmjs.com/package/ng2-validation . Posiada Wbudowany equaloraz equalTometod i dobrej dokumentacji!
Michelangelo

Odpowiedzi:


148

Aby w pewnym sensie powtórzyć metody opublikowane przez innych, w ten sposób tworzę FormGroupwalidatory, które nie obejmują wielu grup.

W tym przykładzie po prostu podaj nazwy kluczy pól passwordi confirmPassword.

// Example use of FormBuilder, FormGroups, and FormControls
this.registrationForm = fb.group({
  dob: ['', Validators.required],
  email: ['', Validators.compose([Validators.required,  emailValidator])],
  password: ['', Validators.required],
  confirmPassword: ['', Validators.required],
  firstName: ['', Validators.required],
  lastName: ['', Validators.required]
}, {validator: matchingPasswords('password', 'confirmPassword')})

Aby Validatorspobrać parametry, muszą zwrócić a functionz parametrem FormGrouplub FormControljako parametr. W tym przypadku sprawdzam plik FormGroup.

function matchingPasswords(passwordKey: string, confirmPasswordKey: string) {
  return (group: FormGroup): {[key: string]: any} => {
    let password = group.controls[passwordKey];
    let confirmPassword = group.controls[confirmPasswordKey];

    if (password.value !== confirmPassword.value) {
      return {
        mismatchedPasswords: true
      };
    }
  }
}

Technicznie rzecz biorąc, mógłbym zweryfikować dowolne dwie wartości, gdybym znał ich klucze, ale wolę nazwać moje Validatorstak samo, jak błąd, który zwrócą. Funkcję można zmodyfikować, aby pobierała trzeci parametr, który reprezentuje nazwę klucza zwróconego błędu.

Zaktualizowano 6 grudnia 2016 r. (Wersja 2.2.4)

Pełny przykład: https://embed.plnkr.co/ukwCXm/


@Dave << które nie obejmują wielu grup >> Czy naprawdę miałeś na myśli <<, które dotyczą wielu grup >>, czy co? Dzięki
superjos

Wydaje się, że nie usuwa to znaczników alertu, gdy hasła są zgodne z Angular 2 RC.1
datatype_void

Wygląda na to, że „ControlGroups” nie istnieje w wersji 2.0. Użyłem „FormGroup”
Stephen

@superjos Chciałem to powiedzieć. Niektórzy programiści decydują się na utworzenie zagnieżdżonego FormGroupdo obsługi walidacji w wielu polach zamiast umieszczania Validatorna całości.
cyber_dave,

1
Co jeśli mamy hasło, potwierdzamy hasło i email oraz potwierdzamy email? [{validator: matchingPasswords('password', 'confirmPassword')},{validator: matchingEmail('email', 'confirmemail')}] Próbowałem tego, ale to nie działa. Jakieś sugestie ? @Dave
Sharan Ainapurapu

51

Odpowiedź Dave'a była bardzo, bardzo pomocna. Jednak niewielka modyfikacja może pomóc niektórym osobom.

W przypadku konieczności dodania błędów do Controlpól, możesz zachować faktyczną konstrukcję formularza i walidatorów:

// Example use of FormBuilder, ControlGroups, and Controls
this.registrationForm= fb.group({
  dob: ['', Validators.required],
  email: ['', Validators.compose([Validators.required,  emailValidator])],
  password: ['', Validators.required],
  confirmPassword: ['', Validators.required],
  firstName: ['', Validators.required],
  lastName: ['', Validators.required]
}, {validator: matchingPasswords('password', 'confirmPassword')})

Zamiast ustawiać błąd w polu ControlGroup, zrób to na rzeczywistym polu w następujący sposób:

function matchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
  return (group: ControlGroup) => {
    let passwordInput = group.controls[passwordKey];
    let passwordConfirmationInput = group.controls[passwordConfirmationKey];
    if (passwordInput.value !== passwordConfirmationInput.value) {
      return passwordConfirmationInput.setErrors({notEquivalent: true})
    }
  }
}

6
Użyj passwordConfirmationInput.setErrors(passwordConfirmationInput.validator(passwordConfirmationInput))w elsegałęzi, aby zaktualizować poprawnie, gdy zmiana w passwordInputspowoduje, że dane będą prawidłowe.
andraaspar

@andraaspar Próbowałem, ale wyskoczył mi błąd TypeError: passwordConfirmationInput.validator is not a function. Dzieje się tak, ponieważ nie utworzyłem jawnie FormControl z Validators.required. Zostawiłem walidatory puste i zamiast tego użyłem atrybutu „required” na wejściu.
beardedlinuxgeek

6
Było to pomocne, ale zauważyłem, że dokumentacja kątowa ma typ zwrotu {[key: string]: any}, który setErrors(...)nie zwraca (już?). setErrors(...)Nadpisuje również wszelkie błędy, które już istnieją, więc dołączyłem do bieżącego obiektu błędu, takiego jak: let errors = formGroup.controls[passwordConfirmationKey].errors;and if(!errors) errors={};and errors['notEquivalent'] = true;andformGroup.controls[dateControlFirst].setErrors(errors);
Stephen

32

Podczas implementacji walidatorów dla wielu pól formularza, będziesz musiał upewnić się, że walidatory są ponownie oceniane po zaktualizowaniu każdego z formantów formularza. Większość przykładów nie zapewnia rozwiązania dla takiego scenariusza, ale jest to bardzo ważne dla spójności danych i prawidłowego zachowania.

Zobacz moją implementację niestandardowego walidatora dla Angular 2, który bierze to pod uwagę: https://gist.github.com/slavafomin/17ded0e723a7d3216fb3d8bf845c2f30 .

Używam otherControl.valueChanges.subscribe()do nasłuchiwania zmian w innej kontrolce i thisControl.updateValueAndValidity()do wyzwalania kolejnej rundy walidacji, gdy inna kontrolka zostanie zmieniona.


Kopiuję poniższy kod do wykorzystania w przyszłości:

match-other-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;

  }

}

Stosowanie

Oto, jak możesz go używać z formularzami reaktywnymi:

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

Więcej aktualnych walidatorów można znaleźć tutaj: moebius-mlm / ng-validators .


Niezła odpowiedź!! Szukałem takiego rozwiązania od wielu godzin! Zastanów się nad małą zmianą: zamiast tracić odniesienie „this” podczas zwracania funkcji, zwróć funkcję taką jak ta: return (control: FormControl) => {/ * code * /}
Vingtoft

Cieszę się, że mogłem pomóc. Dlaczego potrzebujesz odniesienia do this? Właściwie dobrze jest mieć nazwaną funkcję do celów debugowania.
Slava Fomin II

Występ? działa, ale pod względem wydajności nie uważam, że jest to dobre rozwiązanie. Aktualizacja „thisControl” po zmianie wartości „theOtherControl” spowoduje utworzenie pętli, prawda?
nightElf91

Kiedy należy się wypisać? othercontrol.valuechanges.subscribenigdzie nie został wypisany.
juana pu

@juanapu Zakładam, że Angular zakończy valueChangesobserwowalne, gdy otherControlzostanie zniszczona, co spowoduje również zakończenie subskrypcji. Jednak Twoje obawy mogą być uzasadnione. Sugerowałbym gruntowne debugowanie tego kodu najnowszą wersją Angulara przy użyciu różnych przypadków testowych. Jeśli znajdziesz jakieś problemy, zgłoś się ponownie.
Slava Fomin II

23

Używam Angular 2 RC.5, ale nie mogłem znaleźć ControlGroup, na podstawie pomocnej odpowiedzi od Dave'a. Okazało się, że zamiast tego działa FormGroup. Zrobiłem więc kilka drobnych aktualizacji kodów Dave'a i pomyślałem, że podzielę się nimi z innymi.

W pliku komponentu dodaj import dla FormGroup:

import {FormGroup} from "@angular/forms";

Zdefiniuj swoje dane wejściowe na wypadek konieczności bezpośredniego dostępu do kontrolki formularza:

oldPassword = new FormControl("", Validators.required);
newPassword = new FormControl("", Validators.required);
newPasswordAgain = new FormControl("", Validators.required);

W konstruktorze utwórz wystąpienie formularza:

this.form = fb.group({
  "oldPassword": this.oldPassword,
  "newPassword": this.newPassword,
  "newPasswordAgain": this.newPasswordAgain
}, {validator: this.matchingPasswords('newPassword', 'newPasswordAgain')});

Dodaj funkcję matchingPasswords w swojej klasie:

matchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
  return (group: FormGroup) => {
    let passwordInput = group.controls[passwordKey];
    let passwordConfirmationInput = group.controls[passwordConfirmationKey];
    if (passwordInput.value !== passwordConfirmationInput.value) {
      return passwordConfirmationInput.setErrors({notEquivalent: true})
    }
  }
}

Mam nadzieję, że pomoże to tym, którzy używają RC.5. Zauważ, że nie testowałem jeszcze RC.6.


@Sam Czy zmieniłeś coś, aby działało z ostateczną wersją? to nie działa dla mnie .. Mówi: Argument typu '{validator: (group: FormGroup) => void; } ”nie można przypisać do parametru typu„ ValidatorFn ”.
xtof

Nie, nie musiałem nic zmieniać - dla mnie przykładowy kod powyżej działał z finałem Angular2. Czy używasz dokładnie tego kodu, jak powyżej?
Sam

Dobre rozwiązanie @Chang. Jeśli zmienisz hasło po wpisaniu potwierdzenia hasła. Walidacja nie działa. Możesz spróbowaćif (passwordInput.value !== passwordConfirmationInput.value) { return passwordConfirmationInput.setErrors({ notEquivalent: true }); } else { return passwordConfirmationInput.setErrors(null); }
Mario Shtika

16

Dużo kopania w kanciastym źródle, ale znalazłem lepszy sposób.

constructor(...) {
    this.formGroup = builder.group({
        first_name:        ['', Validators.required],
        matching_password: builder.group({
            password: ['', Validators.required],
            confirm:  ['', Validators.required]
        }, this.matchPassword)
    });

    // expose easy access to passworGroup to html
    this.passwordGroup = this.formGroup.controls.matching_password;
}

matchPassword(group): any {
    let password = group.controls.password;
    let confirm = group.controls.confirm;

    // Don't kick in until user touches both fields   
    if (password.pristine || confirm.pristine) {
      return null;
    }

    // Mark group as touched so we can add invalid class easily
    group.markAsTouched();

    if (password.value === confirm.value) {
      return null;
    }

    return {
      isValid: false
    };
}

Część HTML dotycząca grupy haseł

<div ng-control-group="matching_password" [class.invalid]="passwordGroup.touched && !passwordGroup.valid">
    <div *ng-if="passwordGroup.touched && !passwordGroup.valid">Passwords must match.</div>
    <div class="form-field">
        <label>Password</label>
        <input type="password" ng-control="password" placeholder="Your password" />
    </div>
    <div class="form-field">
        <label>Password Confirmation</label>
        <input type="password" ng-control="confirm" placeholder="Password Confirmation" />
    </div>
</div>

Czy po uruchomieniu sprawdzania poprawności dopasowania_hasła obliczana jest również kontrolka firstName? Czego bym nie chciał!
Pascal

16

Aby rozwinąć odpowiedź Matthewdaniela, ponieważ nie jest ona dokładnie poprawna. Oto przykładowy kod, który pokazuje, jak poprawnie przypisać walidator do pliku ControlGroup.

import {Component} from angular2/core
import {FormBuilder, Control, ControlGroup, Validators} from 'angular2/common'

@Component({
  selector: 'my-app',
  template: `
    <form [ngFormModel]="form">
      <label for="name">Name:</label>
      <input id="name" type="text" ngControl="name">
      <br>
      <label for="email">Email:</label>
      <input id="email" type="email" ngControl="email">
      <br>
      <div ngControlGroup="matchingPassword">
        <label for="password">Password:</label>
        <input id="password" type="password" ngControl="password">
        <br>
        <label for="confirmPassword">Confirm Password:</label>
        <input id="confirmPassword" type="password" ngControl="confirmPassword">
      </div>
    </form>
    <p>Valid?: {{form.valid}}</p>
    <pre>{{form.value | json}}</pre>
  `
})
export class App {
  form: ControlGroup
  constructor(fb: FormBuilder) {
    this.form = fb.group({
      name: ['', Validators.required],
      email: ['', Validators.required]
      matchingPassword: fb.group({
        password: ['', Validators.required],
        confirmPassword: ['', Validators.required]
      }, {validator: this.areEqual})
    });
  }

  areEqual(group: ControlGroup) {
    let val;
    let valid = true;

    for (name in group.controls) {
      if (val === undefined) {
        val = group.controls[name].value
      } else {
        if (val !== group.controls[name].value) {
          valid = false;
          break;
        }
      }
    }

    if (valid) {
      return null;
    }

    return {
      areEqual: true
    };
  }
}

Oto działający przykład: http://plnkr.co/edit/Zcbg2T3tOxYmhxs7vaAm?p=preview


co jeśli dodamy radiobuttons i checkbox, jak uzyskać wartość tych dwóch?
Pardeep Jain

2
ControlGroupjest usuwany na korzyść FormGroupkażdego, kto to ogląda. Docs and Learn Angular2 Przykład
miękko

2

Oto kolejna opcja, którą udało mi się wymyślić, która nie zależy od całości lub sub, ControlGroupale jest bezpośrednio powiązana z każdym z nich Control.

Problem, który miałem, polegał na tym, że kontrolki, które były od siebie zależne, nie były hierarchicznie połączone, więc nie mogłem utworzyć pliku ControlGroup. Ponadto, mój CSS został skonfigurowany tak, że każda kontrolka wykorzystywałaby istniejące klasy kątowe, aby określić, czy wyświetlać style błędów, co było bardziej skomplikowane w przypadku walidacji grupowej zamiast walidacji specyficznej dla kontrolki. Próba ustalenia, czy pojedyncza kontrola była ważna, nie była możliwa, ponieważ walidacja była powiązana z grupą kontroli, a nie z każdą indywidualną kontrolą.

W moim przypadku chciałem, aby wartość pola wyboru określała, czy inne pole będzie wymagane, czy nie.

Jest to tworzone przy użyciu konstruktora formularzy w komponencie. W przypadku modelu wyboru zamiast bezpośredniego powiązania go z wartością obiektu żądania powiązałem go z funkcjami pobierania / ustawiania, które pozwolą mi obsługiwać zdarzenia „przy zmianie” dla kontrolki. Wtedy będę mógł ręcznie ustawić walidację dla innej kontrolki w zależności od nowej wartości wybranych kontrolek.

Oto odpowiednia część widoku:

<select [ngFormControl]="form.controls.employee" [(ngModel)]="employeeModel">
  <option value="" selected></option>
  <option value="Yes">Yes</option>
  <option value="No">No</option>
</select>
...
<input [ngFormControl]="form.controls.employeeID" type="text" maxlength="255" [(ngModel)]="request.empID" />

Odpowiednia porcja składnika:

export class RequestComponent {
  form: ControlGroup;
  request: RequestItem;

  constructor(private fb: FormBuilder) {
      this.form = fb.group({
        employee: new Control("", Validators.required),
        empID: new Control("", Validators.compose([Validators.pattern("[0-9]{7}"]))
      });

  get employeeModel() {
    return this.request.isEmployee;
  }

  set employeeModel(value) {
    this.request.isEmployee = value;
    if (value === "Yes") {
      this.form.controls["empID"].validator = Validators.compose([Validators.pattern("[0-9]{7}"), Validators.required]);
      this.form.controls["empID"].updateValueAndValidity();
    }
    else {
      this.form.controls["empID"].validator = Validators.compose([Validators.pattern("[0-9]{7}")]);
      this.form.controls["empID"].updateValueAndValidity();
    }
  }
}

W moim przypadku zawsze miałem walidację wzorca powiązaną z kontrolką, więc validatorjest zawsze ustawiona na coś, ale myślę, że możesz ustawić na validatornull, jeśli nie masz żadnej walidacji powiązanej z kontrolką.

AKTUALIZACJA: Istnieją inne metody przechwytywania zmian modelu, takie jak (ngModelChange)=changeFunctionName($event)lub subskrybowanie zmian wartości kontrolnych przy użyciuthis.form.controls["employee"].valueChanges.subscribe(data => ...))



1

equalToRównież tego szukałem i ostatecznie korzystałem z pakietu ng2-validation ( https://www.npmjs.com/package/ng2-validation )

Oto przykład: Na podstawie szablonu:

<input type="password" ngModel name="password" #password="ngModel" required/>
<p *ngIf="password.errors?.required">required error</p>
<input type="password" ngModel name="certainPassword" #certainPassword="ngModel" [equalTo]="password"/>
<p *ngIf="certainPassword.errors?.equalTo">equalTo error</p>

Oparty na modelu:

let password = new FormControl('', Validators.required);
let certainPassword = new FormControl('', CustomValidators.equalTo(password));

this.form = new FormGroup({
  password: password,
  certainPassword: certainPassword
});

Szablon:

<form [formGroup]="form">
  <input type="password" formControlName="password"/>
  <p *ngIf="form.controls.password.errors?.required">required error</p>
  <input type="password" formControlName="certainPassword"/>
  <p *ngIf="form.controls.certainPassword.errors?.equalTo">equalTo error</p>
</form>

1

Oto moja wersja, której użyłem, aby upewnić się, że wiek w jednej dziedzinie jest większy lub równy wiekowi w innej dziedzinie. Używam również grup formularzy, więc używam group.getraczej funkcji niżgroup.controls[]

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

export function greaterThanOrEqualTo(sourceKey: string, targetKey: string) {
    return (group: FormGroup) => {
        let sourceInput = group.get(sourceKey);
        let targetInput = group.get(targetKey);

        console.log(sourceInput);
        console.log(targetInput);

        if (targetInput.value < sourceInput.value) {
            return targetInput.setErrors({ notGreaterThanOrEqualTo: true })
        }
    }
}

A w komponencie:

    this.form = this._fb.group({

        clientDetails: this._fb.group({
            currentAge: ['', [Validators.required, Validators.pattern('^((1[89])|([2-9][0-9])|100)$')]],
            expectedRetirementAge: ['', [Validators.required]]
        }),

    },
    {
        validator: greaterThanOrEqualTo('clientDetails.currentAge', 'clientDetails.expectedRetirementAge')
    });

0

Myślę, że najlepszym rozwiązaniem na razie jest utworzenie grupy, która będzie sprawować kontrolę. Podczas tworzenia wystąpienia przepustki Control w funkcji, aby ją zweryfikować. przykład:

    this.password = new Control('', Validators.required);
    let x = this.password;
    this.confirm = new Control('', function(c: Control){
        if(typeof c.value === 'undefined' || c.value == "") return {required: "password required"};
        if(c.value !== x.value)
            return {error: "password mismatch"};
        return null;
    });

Wiem, że jest to wysoce zależne od używanej wersji angularjs2. Zostało to przetestowane pod kątem wersji 2.0.0-alpha.46

Jeśli ktoś ma lepsze sugestie, takie jak napisanie własnego walidatora (co może być najlepszym rozwiązaniem), jest mile widziane.

EDYTOWAĆ

możesz także użyć ControlGroup i w pełni zweryfikować tę grupę.

this.formGroup = new ControlGroup({}, function(c: ControlGroup){
        var pass: Control = <Control>c.controls["password"];
        var conf: Control = <Control>c.controls["confirm"];
        pass.setErrors(null, true);
        if(pass.value != null && pass.value != ""){
            if(conf.value != pass.value){
                pass.setErrors({error: "invalid"}, true);
                return {error: "error"};
            }
        }
        return null;
    });

Po prostu edytuj wiadomości zgodnie ze swoją domeną.


0

Odpowiedź Louisa Cruza była dla mnie bardzo pomocna.

Aby zakończyć, po prostu dodaj do else reset setErrors: return passwordConfirmationInput.setErrors (null);

I wszystko działa dobrze!

Dzięki Ci,

Pozdrowienia,

TGA


0

Angular 8 Przykład sprawdzania poprawności w polu potwierdzenia hasła

FYI: to nie zaktualizuje walidacji w polu passwordConfirm, jeśli główne pole "hasło" zostanie zmienione po tym, jak ta walidacja przeszła. Możesz jednak unieważnić pole potwierdzenia hasła, gdy użytkownik wpisze w pole hasła

<input
  type="password"
  formControlName="password"
  (input)="registerForm.get('passwordConfirm').setErrors({'passwordMatches': true})"
/>

register.component.ts

import { PasswordConfirmValidator } from './password-confirm-validator';
export class RegisterComponent implements OnInit {
  registerForm: FormGroup = this.createRegisterForm({
    username: new FormControl('', [Validators.required, Validators.email]),
    password: new FormControl('', [
      Validators.required,
      Validators.pattern('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$'),
      Validators.minLength(8)
    ]),
    passwordConfirm: new FormControl('', [
      Validators.required,
      PasswordConfirmValidator //custom validator
    ])
  });
}

password-confirm-validator.ts

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

export function PasswordConfirmValidator(control: AbstractControl) {
  if(void 0 === control){ return null; }
  if(
    void 0 !== control.parent &&
    void 0 !== control.parent.controls &&
    void 0 !== control.parent.controls['password'] &&
    control.parent.controls['password'].value === control.value
  ){
    return null;
  }
  return {passwordMatches: true};
}

register.component.html

{{registerForm.get('passwordConfirm').hasError('passwordMatches')}}

-2

Proponuję skorzystać z biblioteki ng-form-rules. Jest to niesamowita biblioteka do tworzenia wszelkiego rodzaju formularzy z logiką walidacji oddzieloną od komponentu, która może zależeć od zmian wartości w innych obszarach formularza. Mają świetną dokumentację , przykłady i film, który pokazuje kilka jego funkcji . Wykonywanie takiej weryfikacji, co próbujesz zrobić, jest trywialne.

Możesz sprawdzić ich README, aby uzyskać informacje na wysokim poziomie i podstawowy przykład.


2
Nie podoba mi się pomysł, że istnieje biblioteka do wszystkiego ... biblioteki nie są rozwiązaniem tego problemu. Często będziesz tworzyć nowe problemy, używając tylko innej biblioteki, a także musisz aktualizować te rzeczy podczas aktualizacji Angular. Dlaczego nie użyć form kątowych zgodnie z zamierzeniami ramy?
Nadine

-3

Hasło w Angular 4 jest zgodne z regułami weryfikacji.

Jeśli potrzebujesz błędów kontrolnych pól, możesz to zrobić.

createForm() {
    this.ngForm = this.fb.group({
       'first_name': ["", Validators.required ],
       'last_name' : ["", Validators.compose([Validators.required, Validators.minLength(3)]) ],
       'status' : ['active', Validators.compose([Validators.required])],
       'phone':[null],
       'gender':['male'],
       'address':[''],
       'email':['', Validators.compose([
          Validators.required, 
          Validators.email])],
       'password':['', Validators.compose([Validators.required])],
       'confirm_password':['', Validators.compose([Validators.required])]
    }, {validator: this.matchingPassword('password', 'confirm_password')});
  }

Następnie musisz zadeklarować tę metodę w constructormetodzie Like as.

constructor(
    private fb: FormBuilder

    ) {
    this.createForm();
  }

Zamiast ustawiać błąd w ControlGroup, zrób to na rzeczywistym polu w następujący sposób:

    matchingPassword(passwordKey: string, confirmPasswordKey: string) {
  return (group: FormGroup): {[key: string]: any} => {
    let password = group.controls[passwordKey];
    let confirm_password = group.controls[confirmPasswordKey];

    if (password.value !== confirm_password.value) {
      return {        
        mismatchedPasswords: true
      };
    }
  }
}

Część HTML dotycząca grupy haseł

<form [formGroup]="ngForm" (ngSubmit)="ngSubmit()">
    <div class="form-group">
            <label class="control-label" for="inputBasicPassword"> Password <span class="text-danger">*</span></label>
                <input type="password" class="form-control" formControlName="password" placeholder="Password" name="password" required>
                <div class="alert text-danger" *ngIf="!ngForm.controls['password'].valid && ngForm.controls['password'].touched">This Field is Required.</div>
            </div>
            {{ngForm.value.password | json}}
            <div class="form-group">
            <label class="control-label" for="inputBasicPassword">Confirm Password <span class="text-danger">*</span></label>
                <input type="password" class="form-control" name="confirm_password" formControlName="confirm_password" placeholder="Confirm Password" match-password="password">

    <div class='alert text-danger' *ngIf="ngForm.controls.confirm_password.touched && ngForm.hasError('mismatchedPasswords')">
              Passwords doesn't match.
      </div>
    </div>
<button type="submit" [disabled]="!ngForm.valid" class="btn btn-primary ladda-button" data-plugin="ladda" data-style="expand-left" disabled="disabled"><span class="ladda-label">
            <i class="fa fa-save"></i>  Create an account
        <span class="ladda-spinner"></span><div class="ladda-progress" style="width: 0px;"></div>
        </span><span class="ladda-spinner"></span></button>
</form>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.