Einführung in Formulare in Winkel 4 Erstellen von Validatoren für benutzerdefinierte Formulare

Dies ist der dritte Teil der Serie zum Erstellen von Formularen in Angular. In den ersten beiden Tutorials haben wir den vorlagen- und modellgesteuerten Ansatz von Angular zum Erstellen von Formularen verwendet. Während wir beide Ansätze detailliert beschrieben haben, haben wir jedoch nicht auf benutzerdefinierte Validatorfunktionen eingegangen. In diesem Lernprogramm erfahren Sie alles, was Sie zum Schreiben von benutzerdefinierten Validatoren benötigen, die Ihren Anforderungen entsprechen.

Voraussetzungen

Sie müssen nicht Teil 1 oder 2 dieser Serie befolgt haben, damit Teil 3 Sinn ergibt. Wenn Sie mit Angular jedoch noch nicht vertraut sind, sollten Sie zum ersten Lernprogramm dieser Serie übergehen und von dort aus beginnen. 

Nehmen Sie ansonsten eine Kopie dieses Codes aus unserem GitHub-Repo und verwenden Sie diesen als Ausgangspunkt.  

Eingebaute Validatoren

Angular verfügt nicht über eine große integrierte Validator-Bibliothek. In Angular 4 haben wir folgende beliebte Validatoren in Angular:

  • erforderlich
  • minimale Länge
  • maximale Länge
  • Muster

Es gibt tatsächlich ein paar mehr, und Sie können die vollständige Liste in den Angular-Dokumenten sehen. 

Wir können die obigen integrierten Validatoren auf zwei Arten verwenden:

1. Als Anweisungen in vorlagengesteuerten Formularen.

2. Als Prüfer im FormControl Konstruktor in modellgetriebenen Formen.

name = new FormControl (", Validators.required) 

Wenn die obige Syntax nicht sinnvoll ist, folgen Sie meinen vorherigen Tutorials zum Erstellen eines Anmeldeformulars mithilfe eines vorlagengesteuerten Ansatzes oder eines modellgesteuerten Ansatzes und kehren Sie dann zurück!

Die integrierten Formularvalidierer decken kaum alle Anwendungsfälle ab, die für eine praktische Anwendung erforderlich sind. Beispielsweise muss ein Anmeldeformular möglicherweise prüfen, ob die Werte der Kennwort- und Kennwortbestätigungsfelder übereinstimmen, und eine Fehlermeldung anzeigen, wenn sie nicht übereinstimmen. Ein weiteres allgemeines Beispiel ist ein Prüfer, der E-Mails aus einer bestimmten Domäne auf die schwarze Liste setzt. 

Hier ist eine Tatsache: Vorlagengesteuerte Formulare sind nur modellgesteuerte Formulare darunter. In einem vorlagengesteuerten Formular lassen wir die Vorlage für die Modellerstellung übernehmen. Die offensichtliche Frage ist nun, wie Sie einen Validator an ein Formular anhängen?

Validatoren sind nur Funktionen. In einem modellgesteuerten Formular ist das Anfügen von Validatoren an FormControl unkompliziert. In einem vorlagengesteuerten Formular muss jedoch etwas mehr getan werden. Zusätzlich zur Validatorfunktion müssen Sie eine Direktive für den Validator schreiben und Instanzen der Direktive in der Vorlage erstellen.

Eintauchen in die Details

Obwohl dies bereits besprochen wurde, werden wir den Code für das Anmeldeformular kurz rekapitulieren. Erstens, hier ist der reaktive Ansatz.

app / signup-form / signup-form.component.ts

 // Verwenden Sie den Formbuilder, um das Formularmodell zu erstellen. This.signupForm = this.fb.group (email: [", [Validators.required, Validators.pattern ('[a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [az] 2,3 $ ')]], Kennwort: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8 )]], confirmPwd: [", [Validators.required, Validators.minLength (8)]]], Validator: PasswordMatch), Geschlecht: [", Validators.required],)

FormBuilder ist ein Syntaxzucker, der das erzeugt Gruppe formen und FormControl Instanzen. EIN FormControl verfolgt den Wert und den Validierungsstatus eines einzelnen Formularelements. EIN Gruppe formen, auf der anderen Seite umfasst eine Gruppe von FormControl Instanzen, und es verfolgt den Wert und die Gültigkeit der gesamten Gruppe.

Hier ist die Struktur, die wir verfolgt haben:

FormGroup -> 'signupForm' FormControl -> 'E-Mail' FormGroup -> 'Passwort' FormControl -> 'pwd' FormControl -> 'confirmPwd' FormControl -> 'gender' 

Abhängig von den Anforderungen können wir einen Validator an a anschließen FormControl oder ein Gruppe formen. Ein E-Mail-Blacklisting-Validator muss an das E-Mail angehängt werden FormControl Instanz der E-Mail. 

Für komplexere Überprüfungen, bei denen mehrere Kontrollfelder miteinander verglichen und validiert werden müssen, ist es jedoch besser, die Validierungslogik dem übergeordneten Element hinzuzufügen Gruppe formen. Wie du siehst, Passwort hat ein Gruppe formen Das macht es uns leicht, Validatoren zu schreiben, die die Gleichheit von überprüfen pwd und ConfirmPwd.

Für das vorlagengesteuerte Formular geht die gesamte Logik in die HTML-Vorlage, und hier ein Beispiel:

app / signup-form / signup-form.component.html

ngModel erstellt eine Instanz von FormControl und bindet es an ein Formularsteuerelement. Ähnlich, ngModelGroup erstellt und bindet ein Gruppe formen Instanz zu einem DOM-Element. Sie teilen dieselbe Modelldomänenstruktur, die oben erläutert wurde. 

Es ist auch interessant, das zu beachten FormControl, Gruppe formen, und FormArray Erweitere AbstractControl Klasse. Was das bedeutet, ist das AbstractControl class ist dafür verantwortlich, die Werte von Formularobjekten zu verfolgen, sie zu überprüfen und andere Dinge wie unberührte, schmutzige und berührte Methoden zu aktivieren. 

Nun, da wir beide Formulartechniken kennen, schreiben wir unseren ersten benutzerdefinierten Prüfer.

Benutzerdefinierte Überprüfungsfunktion für modellgesteuerte Formulare

Validatoren sind Funktionen, die ein FormControl/Gruppe formen Instanz als Eingabe und zurückkehren Null oder ein Fehlerobjekt. Null wird zurückgegeben, wenn die Überprüfung erfolgreich war, und wenn nicht, wird das Fehlerobjekt ausgegeben. Hier ist eine sehr grundlegende Version einer Validierungsfunktion. 

app / password-match.ts

importieren Sie FormGroup aus '@ angle / forms'; Exportfunktion passwordMatch (Steuerelement: FormGroup): [Schlüssel: Zeichenfolge]: Boolean 

Ich habe eine Funktion deklariert, die eine Instanz von akzeptiert Gruppe formen als Eingabe. Es gibt ein Objekt mit einem Schlüssel vom Typ string und einem true / false-Wert zurück. Auf diese Weise können wir ein Fehlerobjekt des folgenden Formulars zurückgeben:

mismatch: true

Als nächstes müssen wir den Wert von pwd und ConfirmPwd FormControl-Instanzen. Ich werde verwenden control.get () ihre Werte holen. 

Exportfunktion passwordMatch (Steuerelement: FormGroup): [Schlüssel: String]: Boolean // Pwd abrufen und ConfirmPwd mit control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd');  

Jetzt müssen wir den Vergleich durchführen und dann entweder null oder ein Fehlerobjekt zurückgeben.

app / password-match.ts

AbstractControl aus '@ angle / forms' importieren; Exportfunktion passwordMatch (Steuerelement: AbstractControl): [Schlüssel: String]: Boolean // Pwd abrufen und ConfirmPwd mithilfe von control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Wenn FormControl-Objekte nicht vorhanden sind, geben Sie null zurück, wenn (! Pwd ||! ConfirmPwd) null zurückgibt. // Wenn sie tatsächlich gleich sind, Rückgabe null wenn (pwd.value === confirmPwd.value) return null;  // Else return false return Nichtübereinstimmung: true;  

Warum habe ich ersetzt? Gruppe formen mit AbstractControl? Wie du weißt, AbstractControl ist die Mutter aller Form * -Klassen und gibt Ihnen mehr Kontrolle über die Formularsteuerungsobjekte. Dies hat den zusätzlichen Vorteil, dass der Validierungscode konsistenter wird.

Importieren Sie die passwordMatch Funktion in der Anmeldeformular Komponente und deklarieren Sie es als Prüfer für das Passwort Gruppe formen Beispiel.

app / password-match.ts

importieren Sie passwordMatch aus './… / password-match';… export class SignupFormComponent implementiert OnInit ngOnInit () // Erstellen Sie mit dem Formbuilder das Formularmodell this.signupForm = this.fb.group (… password: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8)]), confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: passwordMatch ),…) 

Fehler anzeigen

Wenn du alles richtig gemacht hast, Passwort.Fehler? .Match ist wahr, wenn die Werte beider Felder nicht übereinstimmen.

password.errors? .mismatch json

Obwohl es alternative Möglichkeiten zur Anzeige von Fehlern gibt, werde ich das verwenden ngIf Anweisung, ob eine Fehlermeldung angezeigt werden soll oder nicht.

Zuerst werde ich verwenden ngIf um zu sehen, ob das Passwort ungültig ist. 

  

Wir gebrauchen Passwort.berührt um sicherzustellen, dass der Benutzer nicht mit Fehlern begrüßt wird, bevor eine Taste gedrückt wurde.

Als Nächstes werde ich den Ausdruck ngIf = "und dann eine else b" -Syntax verwenden, um den richtigen Fehler anzuzeigen.

app / signup-form / signup-form.component.html

    Passwort stimmt nicht überein   Das Passwort muss aus mehr als 8 Zeichen bestehen 

Dort haben Sie es, ein Arbeitsmodell des Validators, das die Passwortgleichheit prüft.

Demo für benutzerdefinierte Validatoren in modellgetriebenen Formularen

Benutzerdefinierte Validiererrichtlinie für vorlagengesteuerte Formulare

Wir werden dieselbe Validierungsfunktion verwenden, die wir zuvor für das modellgesteuerte Formular erstellt haben. Wir haben jedoch keinen direkten Zugriff auf Instanzen von FormControl/Gruppe formen in einer vorlagengesteuerten Form. Damit der Validator funktioniert, müssen Sie Folgendes tun:

  1. Ein ... kreieren PasswordMatchDirective das dient als Hülle um die passwordMatch Prüferfunktion. Wir werden die Direktive als Validator mit der. Registrieren NG_VALIDATORS Anbieter. Mehr dazu später.
  2. Hängen Sie die Direktive an das Formularsteuerelement der Vorlage an. 

Schreiben wir zuerst die Direktive. So sieht eine Anweisung in Angular aus:

app / password-match.ts

AbstractControl aus '@ angle / forms' importieren; Exportfunktion passwordMatch (Steuerelement: AbstractControl): [Schlüssel: String]: Boolean // Pwd abrufen und ConfirmPwd mithilfe von control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Wenn FormControl-Objekte nicht vorhanden sind, geben Sie null zurück, wenn (! Pwd ||! ConfirmPwd) null zurückgibt. // Wenn sie tatsächlich gleich sind, Rückgabe null wenn (pwd.value === confirmPwd.value) return null;  // Else return false return Nichtübereinstimmung: true;  // PasswordMatchDirective @Directive (Auswahl: ", Provider: []) Exportklasse PasswordMatchDirective 

Das @ Direktion Dekorateur wird verwendet, um die Klasse als Angular-Direktive zu kennzeichnen. Es akzeptiert ein Objekt als Argument, das die Metadaten der Direktivekonfiguration angibt, z. B. Selektoren, für die die Direktive angefügt werden soll, und die Liste der einzubringenden Anbieter. Geben Sie die Metadaten der Direktive ein:

app / password-match.ts

@Directive (Selector: '[passwordMatch] [ngModelGroup] ", // 1 Provider: [// 2 bereitstellen: NG_VALIDATORS, useValue: passwordMatch, multi: true]) Exportklasse PasswordMatchDirective 
  1. Die Direktive ist jetzt an alle Eingabesteuerelemente angehängt, die über die Attribute verfügen ngModelGroup und passwordMatch
  2. Wir erweitern die eingebauten Validatoren mit der NG_VALIDATORS Anbieter. Wie vorab erwähnt, NG_VALIDATORS ist ein Anbieter mit einer erweiterbaren Sammlung von Prüfern. Das passwordMatch Eine zuvor erstellte Funktion wird als Abhängigkeit deklariert. Das multi: wahr legt diesen Anbieter als Multi-Anbieter fest. Dies bedeutet, dass wir die bestehende Sammlung von Validatoren, die von bereitgestellt werden, ergänzen werden NG_VALIDATORS.

Fügen Sie nun die Anweisung dem Deklarations-Array in hinzu ngModule.

app / app.module.ts

… PasswordMatchDirective aus './password-match' importieren; @NgModule (Deklarationen: [AppComponent, SignupFormComponent, PasswordMatchDirective]) importiert: [BrowserModule, FormsModule], Anbieter: [], Bootstrap: [AppComponent]) Exportklasse AppModule  

Fehlermeldungen anzeigen

Um die Validierungsfehlermeldungen anzuzeigen, verwende ich dieselbe Vorlage, die wir für die modellgesteuerten Formulare erstellt haben.

 
Passwort stimmt nicht überein Das Passwort muss aus mehr als 8 Zeichen bestehen

Fazit

In diesem Lernprogramm haben wir gelernt, benutzerdefinierte Angular-Validatoren für Formulare in Angular zu erstellen. 

Validatoren sind Funktionen, die null oder ein Fehlerobjekt zurückgeben. In modellgesteuerten Formularen müssen wir den Validator an eine FormControl / FormGroup-Instanz anhängen. In einem vorlagengesteuerten Formular war die Prozedur etwas komplexer, da über der Validatorfunktion eine Direktive erstellt werden musste. 

Wenn Sie daran interessiert sind, mehr über JavaScript zu lernen, denken Sie daran, was wir in Envato Market haben.

Ich hoffe, dass Ihnen diese Serie zu Forms in Angular gefallen hat. Ich würde gerne deine Gedanken hören. Teilen Sie sie durch die Kommentare.