Einführung in Formulare in Winkel 4 Vorlagengesteuerte Formulare

Was Sie erstellen werden

Formulare sind für jede moderne Front-End-Anwendung von entscheidender Bedeutung, und sie werden von uns täglich verwendet, auch wenn sie es nicht bemerken. Formulare sind erforderlich, um einen Benutzer sicher bei der App anzumelden, nach allen verfügbaren Hotels in einer bestimmten Stadt zu suchen, ein Taxi zu buchen, eine To-Do-Liste zu erstellen und eine Menge anderer Dinge zu erledigen, die wir gewohnt sind. Einige Formulare haben nur ein paar Eingabefelder, während andere Formulare ein Feld von Feldern haben können, die sich auf einige Seiten oder Registerkarten erstrecken. 

In diesem Lernprogramm werden verschiedene Strategien für die Entwicklung von Formularen in Angular beschrieben. Unabhängig von der gewählten Strategie sollten die Formularbibliotheken Folgendes umfassen:

  • Unterstützung der bidirektionalen Bindung, sodass die Eingabesteuerungswerte mit dem Komponentenstatus synchron sind.
  • Verfolgen Sie den Formularstatus und verwenden Sie visuelle Hinweise, um den Benutzer darüber zu informieren, ob der aktuelle Status gültig ist oder nicht. Wenn der Benutzername beispielsweise ungültige Zeichen enthält, sollte ein roter Rahmen um das Eingabefeld für den Benutzernamen angezeigt werden.
  • Besitze einen Mechanismus, um Validierungsfehler richtig anzuzeigen.
  • Aktivieren oder deaktivieren Sie bestimmte Teile des Formulars, sofern nicht einige Validierungskriterien erfüllt sind.

Einführung in Formulare in Winkel

Angular als vollwertiges Frontend-Framework verfügt über eigene Bibliotheken zum Erstellen komplexer Formulare. Die neueste Version von Angular bietet zwei leistungsstarke Strategien zum Erstellen von Formularen. Sie sind:

  • vorlagengesteuerte Formulare 
  • Modellgetriebene oder reaktive Formen

Beide Technologien gehören zum @ eckig / formen Bibliothek und basieren auf den gleichen Formularsteuerungsklassen. Sie unterscheiden sich jedoch bemerkenswert in ihrer Philosophie, ihrem Programmierstil und ihrer Technik. Die Auswahl einer Option hängt von Ihrem persönlichen Geschmack und auch von der Komplexität der Form ab, die Sie erstellen möchten. Meiner Meinung nach sollten Sie zuerst beide Ansätze ausprobieren und dann einen auswählen, der zu Ihrem Stil und dem Projekt passt. 

Im ersten Teil des Lernprogramms werden vorlagengesteuerte Formulare mit einem praktischen Beispiel behandelt: Erstellen eines Anmeldeformulars mit Validierung für alle Formularfelder. Im zweiten Teil dieses Lernprogramms werden die Schritte zum Erstellen desselben Formulars mithilfe eines modellgesteuerten Ansatzes nachvollzogen. 

Vorlagengesteuerte Formulare

Der auf Vorlagen basierende Ansatz ist eine Strategie, die der AngularJS-Ära entlehnt wurde. Meiner Meinung nach ist dies die einfachste Methode zum Erstellen von Formen. Wie funktioniert es? Wir werden einige Angular-Direktiven verwenden. 

Mithilfe von Direktiven können Sie Verhalten mit Elementen im DOM verknüpfen.
- Winkeldokumentation

Angular bietet formularspezifische Anweisungen, mit denen Sie die Formulareingabedaten und das Modell binden können. Die formularspezifischen Anweisungen fügen einem einfachen HTML-Formular zusätzliche Funktionen und Verhalten hinzu. Das Endergebnis ist, dass die Vorlage die verbindlichen Werte bei der Modell- und Formularvalidierung berücksichtigt. 

In diesem Lernprogramm verwenden wir vorlagengesteuerte Formulare zum Erstellen der Anmeldeseite einer Anwendung. Das Formular umfasst die am häufigsten verwendeten Formularelemente und verschiedene Validierungsprüfungen für diese Formularelemente. Hier sind die Schritte, die Sie in diesem Lernprogramm befolgen werden.

  • Fügen Sie FormsModule zu hinzu app.module.ts.
  • Erstellen Sie eine Klasse für das Benutzermodell.
  • Erstellen Sie die ersten Komponenten und das Layout für das Anmeldeformular.
  • Verwenden Sie winklige Anweisungen wie ngModelngModelGroup, und ngForm.
  • Validierung mit integrierten Validatoren hinzufügen.
  • Validierungsfehler sinnvoll anzeigen.
  • Formulareinreichung mit ngSubmit.

Lass uns anfangen.

Voraussetzungen

Der Code für dieses Projekt ist auf meinem GitHub-Repo verfügbar. Laden Sie die ZIP-Datei herunter oder klonen Sie das Repo, um es in Aktion zu sehen. Wenn Sie lieber von vorne anfangen möchten, vergewissern Sie sich, dass Angular CLI installiert ist. Verwenden Sie die ng Befehl zum Erzeugen eines neuen Projekts. 

$ ng neues SignupFormProject

Generieren Sie anschließend eine neue Komponente für die SignupForm.

ng generiert die Komponente SignupForm

Ersetzen Sie den Inhalt von app.component.html mit diesem:

 

Hier ist die Verzeichnisstruktur für die src / Verzeichnis. Ich habe einige nicht wesentliche Dateien entfernt, um die Dinge einfach zu halten.

. ├── app │ app.component.css app.component.html ├── ├── app.component.ts ts. App.module.ts ├── ├── Anmeldeformular-├── ├ ── signup-form.component.css │ up up up up signup-form.component.html │ └── up up up up up up up up up up up... .ts ├── polyfills.ts ├── styles.css ├── tsconfig.app.json └── typings.d.ts 

Wie Sie sehen, ein Verzeichnis für die Anmeldeformular Komponente wurde automatisch erstellt. Das ist, wo der größte Teil unseres Codes gehen wird. Ich habe auch ein neues erstellt User.ts zur Speicherung unseres Benutzermodells.

Die HTML-Vorlage

Bevor wir in die eigentliche Komponentenvorlage eintauchen, müssen wir eine abstrakte Vorstellung davon haben, was wir bauen. Hier ist also die Formstruktur, die ich im Kopf habe. Das Anmeldeformular enthält mehrere Eingabefelder, ein Auswahlelement und ein Kontrollkästchenelement. 


Hier ist die HTML-Vorlage, die wir für unsere Registrierungsseite verwenden werden. 

HTML-Vorlage

 
Anmelden

Die in der HTML-Vorlage verwendeten CSS-Klassen sind Teil der Bootstrap-Bibliothek, mit der Dinge schön gemacht werden. Da dies kein Design-Tutorial ist, werde ich nicht viel über die CSS-Aspekte des Formulars sprechen, sofern dies nicht erforderlich ist. 

Grundlegendes Formular-Setup

Um die vorlagengesteuerten Formularanweisungen verwenden zu können, müssen Sie die importieren FormsModule von @ eckig / formen und füge es dem hinzu Einfuhren Array in app.module.ts.

app / app.module.ts

FormsModule aus '@ angle / forms' importieren; @NgModule (… importiert: [BrowserModule, FormsModule],…) Exportklasse AppModule  

Als Nächstes erstellen Sie eine Klasse, die alle Eigenschaften der Benutzerentität enthält. Wir können entweder eine Schnittstelle verwenden und in der Komponente implementieren oder eine TypeScript-Klasse für das Modell verwenden.

app / User.ts

Exportklasse Benutzer ID: Nummer; E-Mail: Zeichenfolge; // Beide Passwörter befinden sich in einem einzigen Objekt. Password: pwd: string; confirmPwd: Zeichenfolge; ; Geschlecht: String; Begriffe: boolean; Konstruktor (Werte: Object = ) // Konstruktorinitialisierung Object.assign (this, values);  

Erstellen Sie jetzt eine Instanz der Klasse in der SignupForm-Komponente. Ich habe auch eine zusätzliche Eigenschaft für das Geschlecht erklärt. 

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

import Component, OnInit aus '@ angle / core'; // Importieren Sie das Benutzermodell importieren User aus './… / User'; @Component (Selector: 'app-signup-form', templateUrl: './signup-form.component.html', styleUrls: ['./signup-form.component.css']) export-Klasse SignupFormComponent implementiert OnInit // Eigenschaft für das Geschlecht des privaten Geschlechts: string []; // Eigenschaft für den privaten Benutzer des Benutzers: User; ngOnInit () this.gender = ['männlich', 'weiblich', 'andere']; // Ein neues Benutzerobjekt erstellen this.user = neuer Benutzer (email: "", Kennwort: pwd: "", confirm_pwd: "", gender: this.gender [0], terms: false);  

Für die Anmeldeformular.component.html Datei, ich werde die gleiche HTML-Vorlage verwenden, die oben beschrieben wurde, jedoch mit geringfügigen Änderungen. Das Anmeldeformular enthält ein Auswahlfeld mit einer Liste von Optionen. Obwohl dies funktioniert, machen wir es auf die Angular-Weise, indem wir die Liste mit der Schleife durchlaufen ngFor Richtlinie.

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

Anmelden

Als Nächstes möchten wir die Formulardaten an das Benutzerklassenobjekt binden, so dass beim Eingeben der Anmeldedaten in das Formular ein neues Benutzerobjekt erstellt wird, das diese Daten vorübergehend speichert. Auf diese Weise können Sie die Ansicht mit dem Modell synchron halten. Dies wird als Bindung bezeichnet. 

Es gibt mehrere Möglichkeiten, dies zu erreichen. Ich möchte Sie zuerst vorstellen ngModel und ngForm.

ngForm und ngModel

ngForm und ngModel sind Angular-Anweisungen, die für die Erstellung von vorlagengesteuerten Formularen unerlässlich sind. Lass uns beginnen mit ngForm zuerst. Hier ist ein Auszug über ngForm aus den Angular-Dokumenten.

Das NgForm Richtlinie ergänzt die bilden Element mit zusätzlichen Funktionen. Es enthält die Steuerelemente, die Sie für die Elemente erstellt haben, mit einem ngModel Richtlinie und Name Attribut und überwacht deren Eigenschaften, einschließlich ihrer Gültigkeit. Es hat auch ein eigenes gültig Eigenschaft, die nur wahr ist wenn jeder die Kontrolle enthält ist gültig.

Aktualisieren Sie zuerst das Formular mit der ngForm Direktive:

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

#Anmeldeformular ist eine Vorlagenreferenzvariable, die auf die verweist ngForm Richtlinie, die die gesamte Form regelt. Das folgende Beispiel zeigt die Verwendung von a ngForm Referenzobjekt zur Validierung.

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

Hier, signupForm.form.valid gibt false zurück, wenn nicht alle Formularelemente die entsprechenden Validierungsprüfungen bestehen. Die Schaltfläche "Senden" wird deaktiviert, bis das Formular gültig ist.  

Für das Binden der Vorlage und des Modells gibt es viele Möglichkeiten, dies zu tun, und ngModel verfügt über drei verschiedene Syntax, um diese Situation anzugehen. Sie sind:

  1. [(ngModel)] 
  2. [ngModel]
  3. ngModel

Beginnen wir mit dem ersten.

Zweiwege-Bindung mit [(ngModel)]

[(ngModel)] führt eine bidirektionale Bindung zum Lesen und Schreiben von Eingabesteuerungswerten durch. Wenn eine [(ngModel)] Wenn die Direktive verwendet wird, erhält das Eingabefeld einen Anfangswert von der gebundenen Komponentenklasse und aktualisiert diesen immer wieder, wenn eine Änderung des Eingabesteuerungswerts festgestellt wird (bei Tastendruck und Drücken der Taste). Das Bild unten beschreibt den wechselseitigen Bindungsprozess besser.

Hier ist der Code für das E-Mail-Eingabefeld:

 

[(ngModel)] = "user.email" bindet die E-Mail-Eigenschaft des Benutzers an den Eingabewert. Ich habe auch ein hinzugefügt Name Attribut und Satz name = "email". Dies ist wichtig und Sie erhalten eine Fehlermeldung, wenn Sie bei der Verwendung von ngModel kein Namensattribut deklariert haben. 

Fügen Sie auf ähnliche Weise eine [(ngModel)] und ein einzigartiges Name Attribut zu jedem Formularelement. Ihr Formular sollte jetzt ungefähr so ​​aussehen:

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

Das ngModelGroup wird verwendet, um ähnliche Formularfelder zu gruppieren, sodass Validierungen nur für diese Formularfelder ausgeführt werden können. Da beide Kennwortfelder miteinander in Beziehung stehen, werden wir sie einer einzigen ngModelGroup zuordnen. Wenn alles wie erwartet funktioniert, ist die Komponente gebunden Nutzer Diese Eigenschaft sollte für die Speicherung aller Formularsteuerwerte verantwortlich sein. Um dies in Aktion zu sehen, fügen Sie nach dem Formular-Tag Folgendes hinzu:

user | Json

Pipe die Benutzereigenschaft durch die JsonPipe um das Modell als JSON im Browser darzustellen. Dies ist hilfreich beim Debuggen und Protokollieren. Sie sollten eine solche JSON-Ausgabe sehen. 

Die Werte fließen von der Ansicht in das Modell ein. Was ist umgekehrt? Versuchen Sie, das Benutzerobjekt mit einigen Werten zu initialisieren.

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

this.user = neuer Benutzer (// mit einigen Daten-E-Mail-Adresse initialisiert: "[email protected]"), Kennwort: pwd: "", confirm_pwd: "", gender: this.gender [0]);

Und sie erscheinen automatisch in der Ansicht:

"email": "[email protected]", "password": "pwd": "", "confirm_pwd": "", "gender": "männlich"

Die wechselseitige Bindung [(ngModel)] Mit der Syntax können Sie mühelos Formulare erstellen. Es hat jedoch einige Nachteile. Daher gibt es einen alternativen Ansatz, der verwendet wird ngModel oder [ngModel].

Hinzufügen von ngModel zum Mix

Wann ngModel verwendet wird, sind wir tatsächlich dafür verantwortlich, die Komponenteneigenschaft mit den Eingabesteuerungswerten zu aktualisieren und umgekehrt. Die Eingabedaten fließen nicht automatisch in die Benutzereigenschaft der Komponente ein.

Ersetzen Sie also alle Instanzen von [(ngModel)] = "" mit ngModel. Wir werden das behalten Name Attribut, weil alle drei Versionen von ngModel die Name Attribut zur Arbeit. 

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

Mit ngModel, Der Wert des Namensattributs wird zum Schlüssel des Referenzobjekts ngForm Anmeldeformular dass wir früher geschaffen haben. Also zum Beispiel, signupForm.value.email speichert den Steuerwert für die E-Mail-ID. 

Ersetzen user | Json mit signupForm.value | Json denn dort ist jetzt der ganze Staat gespeichert. 

Einseitige Bindung mit [ngModel]

Was ist, wenn Sie den Anfangsstatus der gebundenen Klassenkomponente festlegen müssen? Das ist was der [ngModel] tut für dich. 

Hier fließen die Daten vom Modell zur Ansicht. Nehmen Sie die folgenden Änderungen an der Syntax vor, um die unidirektionale Bindung zu verwenden:

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

Welchen Ansatz sollten Sie wählen? Wenn du verwendest [(ngModel)] und ngForm Zusammen haben Sie schließlich zwei Zustände, die Sie beibehalten müssen-Nutzer und signupForm.value-und das könnte möglicherweise verwirrend sein. 

"email": "[email protected]", "password": "pwd": "thisispassword", "confirm_pwd": "thisispassword", "gender": "männlich" //user.value " email ":" [email protected] "," password ": " pwd ":" thisispassword "," confirm_pwd ":" thisispassword "," gender ":" male " //signupForm.value 

Daher empfehle ich stattdessen die einseitige Bindungsmethode. Aber das entscheiden Sie.

Validierung und Anzeige von Fehlermeldungen 

Hier sind unsere Anforderungen für die Validierung.

  • Alle Formularsteuerelemente sind erforderlich.
  • Deaktivieren Sie die Schaltfläche "Senden", bis alle Eingabefelder gefüllt sind.
  • Das E-Mail-Feld sollte ausschließlich eine E-Mail-ID enthalten.
  • Das Passwortfeld sollte eine Mindestlänge von 8 haben.
  • Sowohl das Passwort als auch die Bestätigung sollten übereinstimmen.
Unser Formular mit gültiger Bestätigung

Der erste ist einfach. Sie müssen eine hinzufügen erforderlich Validierungsattribut für jedes Formularelement wie folgt:

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

Neben dem erforderlich Attribut, ich habe auch ein neues exportiert #Email Vorlagenreferenzvariable. Auf diese Weise können Sie in der Vorlage selbst auf die Angular-Steuerung des Eingabefelds zugreifen. Wir werden es verwenden, um Fehler und Warnungen anzuzeigen. Verwenden Sie nun die deaktivierte Eigenschaft der Schaltfläche, um die Schaltfläche zu deaktivieren:

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

Verwenden Sie zum Hinzufügen einer Einschränkung für E-Mails das Musterattribut, das mit Eingabefeldern funktioniert. Muster werden verwendet, um reguläre Ausdrücke wie den folgenden anzugeben:

pattern = "[a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [a-z] 2,3 $"

Für das Passwort-Feld müssen Sie lediglich ein hinzufügen minlength = "" Attribut:

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

 

Um die Fehler anzuzeigen, verwende ich die bedingte Direktive ngIf auf einem div-Element. Beginnen wir mit dem Eingabefeld für die E-Mail:

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

E-Mail-Feld darf nicht leer sein
Die E-Mail-ID scheint nicht richtig zu sein

Hier ist viel los. Beginnen wir mit der ersten Zeile des Fehlerbereichs.

Erinnere dich an die #Email Variable, die wir früher exportiert haben? Es enthält einige Informationen zum Eingabesteuerungsstatus des E-Mail-Felds. Das beinhaltet: email.valid, email.invalid, email.dirty, email.pristine, email.touched, email.untouched, und email.errors.  Die Abbildung unten beschreibt jede dieser Eigenschaften im Detail.

Also das div Element mit dem * ngIf wird nur ausgegeben, wenn die E-Mail ungültig ist. Der Benutzer wird jedoch mit Fehlern in Bezug auf die leeren Eingabefelder begrüßt, bevor er das Formular bearbeiten kann. 

Um dieses Szenario zu vermeiden, haben wir die zweite Bedingung hinzugefügt. Der Fehler wird erst nach angezeigt Die Kontrolle wurde besucht oder Der Wert des Steuerelements wurde geändert.

Die verschachtelten div-Elemente werden verwendet, um alle Fälle von Validierungsfehlern abzudecken. Wir gebrauchen email.errors um alle möglichen Validierungsfehler zu überprüfen und sie dem Benutzer in Form von benutzerdefinierten Meldungen anzuzeigen. Führen Sie nun die gleichen Schritte für die anderen Formularelemente aus. So habe ich die Validierung für die Passwörter codiert. 

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

 
Das Passwort muss aus mehr als 8 Zeichen bestehen
Passwörter stimmen nicht überein

Dies fängt an, etwas unordentlich auszusehen. Angular verfügt über eine begrenzte Anzahl von Validatorattributen: erforderlich, minimale Länge, maximale Länge, und Muster. Für jedes andere Szenario wie das Vergleichen von Kennwörtern müssen Sie sich auf verschachtelt verlassen ngIf bedingungen wie ich oben. Oder erstellen Sie im Idealfall eine benutzerdefinierte Validierungsfunktion, die ich im dritten Teil dieser Serie behandeln werde.

Im obigen Code habe ich die verwendet ngIf sonst Syntax, die in der neuesten Version von Angular eingeführt wurde. So funktioniert es:

Gültiger Inhalt…
Nicht gültiger Inhalt…

Senden Sie das Formular mit ngSubmit

Wir haben das Formular fast fertiggestellt. Nun müssen wir in der Lage sein, das Formular abzusenden, und die Kontrolle der Formulardaten sollte beispielsweise an eine Komponentenmethode übergeben werden onFormSubmit ().

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

Nun für die Komponente:

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

… Public onFormSubmit (Wert, gültig: Wert: Benutzer, gültig: boolean) this.user = Wert; console.log (this.user); console.log ("gültig:" + gültig); … 

Letzte Demo

Hier ist die endgültige Version der Anwendung. Ich habe ein paar Bootstrap-Klassen hinzugefügt, um das Formular hübsch zu gestalten.

Zusammenfassung

Wir sind alle hier fertig. In diesem Lernprogramm wurde alles behandelt, was Sie zum Erstellen eines Formulars in Angular mit dem vorlagengesteuerten Ansatz benötigen. Vorlagengestützte Formulare sind aufgrund ihrer Einfachheit und Benutzerfreundlichkeit beliebt. 

Wenn Sie jedoch ein Formular mit vielen Formularelementen erstellen müssen, wird dieser Ansatz unübersichtlich. Im nächsten Tutorial werden wir die modellgetriebene Art und Weise beschreiben, mit der dasselbe Formular erstellt wird. 

Teilen Sie Ihre Gedanken in den Kommentaren unten mit.

Lernen Sie JavaScript: Das komplette Handbuch

Wir haben ein umfassendes Handbuch zusammengestellt, mit dessen Hilfe Sie JavaScript erlernen können, egal ob Sie gerade erst als Web-Entwickler anfangen oder sich mit fortgeschrittenen Themen befassen möchten.