Formulieren zijn van cruciaal belang voor elke moderne front-endapplicatie en ze zijn een functie die we elke dag gebruiken, zelfs als we ons dit niet realiseren. Formulieren zijn vereist voor het veilig inloggen bij een gebruiker van de app, het zoeken naar alle beschikbare hotels in een bepaalde stad, het boeken van een taxi, het bouwen van een takenlijst en het doen van talloze andere dingen die we gewend zijn. Sommige formulieren hebben slechts een paar invoervelden, terwijl andere formulieren een reeks velden kunnen hebben die zich uitstrekken tot een paar pagina's of tabbladen.
In deze tutorial zullen we het hebben over verschillende strategieën die beschikbaar zijn voor het ontwikkelen van vormen in Angular. Ongeacht de strategie die u kiest, hier zijn de dingen die een formulierbibliotheek zou moeten omvatten:
Hoekig, zijnde een volwaardig front-end framework, heeft zijn eigen verzameling bibliotheken voor het bouwen van complexe vormen. De nieuwste versie van Angular heeft twee krachtige strategieën voor het samenstellen van vormen. Zij zijn:
Beide technologieën behoren tot de @ Hoekige / formulieren
bibliotheek en zijn gebaseerd op dezelfde formuliercontroleklassen. Ze verschillen echter opmerkelijk in hun filosofie, programmeerstijl en techniek. Het kiezen van een boven de ander hangt af van uw persoonlijke smaak en ook van de complexiteit van de vorm die u probeert te creëren. Naar mijn mening moet je eerst de twee benaderingen proberen en dan een kiezen die bij je stijl en het project past.
Het eerste deel van de tutorial behandelt sjabloongestuurde formulieren met een praktisch voorbeeld: een aanmeldingsformulier bouwen met validatie voor alle formuliervelden. In het tweede deel van deze zelfstudie zullen we de stappen herhalen om dezelfde vorm te maken met behulp van een modelgestuurde aanpak.
De sjabloongestuurde aanpak is een strategie die is ontleend aan het AngularJS-tijdperk. Naar mijn mening is dit de meest eenvoudige methode om formulieren te bouwen. Hoe werkt het? We zullen enkele hoekige richtlijnen gebruiken.
Met richtlijnen kunt u gedrag koppelen aan elementen in de DOM.
- Hoekige documentatie
Angular biedt formulespecifieke richtlijnen die u kunt gebruiken om de formulierinvoergegevens en het model te binden. De vormspecifieke richtlijnen voegen extra functionaliteit en gedrag toe aan een eenvoudig HTML-formulier. Het eindresultaat is dat de sjabloon zorgt voor bindende waarden met het model en formuliervalidatie.
In deze zelfstudie gebruiken we sjabloongestuurde formulieren om de aanmeldingspagina van een toepassing te maken. Het formulier behandelt de meest voorkomende formulierelementen en verschillende validatiecontroles op deze formulierelementen. Dit zijn de stappen die u in deze zelfstudie zult volgen.
app.module.ts
.ngModel
, ngModelGroup
, en ngForm
.ngSubmit
.Laten we beginnen.
De code voor dit project is beschikbaar op mijn GitHub-repo. Download de zip of kloon de repo om deze in actie te zien. Als u liever vanuit nul begint, zorg er dan voor dat u Angular CLI hebt geïnstalleerd. Gebruik de ng
opdracht om een nieuw project te genereren.
$ ng nieuw SignupFormProject
Maak vervolgens een nieuw onderdeel voor het aanmeldingsformulier.
ng component Installatievorm genereren
Vervang de inhoud van app.component.html hiermee:
Hier is de mapstructuur voor de src / directory. Ik heb een aantal niet-essentiële bestanden verwijderd om de dingen eenvoudig te houden.
. ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── inschrijfformulier │ │ ├ ── signup-form.component.css │ │ ├── signup-form.component.html │ │ └── signup-form.component.ts │ └── User.ts ├── index.html ├── main .ts ├── polyfills.ts ├── styles.css ├── tsconfig.app.json └── typings.d.ts
Zoals je kunt zien, een map voor de SignupForm
component is automatisch gemaakt. Dat is waar het grootste deel van onze code zal gaan. Ik heb ook een nieuw gemaakt User.ts
voor het opslaan van ons gebruikersmodel.
Voordat we in de eigenlijke componentsjabloon duiken, moeten we een abstract idee hebben van wat we aan het bouwen zijn. Dus hier is de vormstructuur die ik in gedachten heb. Het aanmeldingsformulier heeft meerdere invoervelden, een select element en een checkbox-element.
Hier is de HTML-sjabloon die we zullen gebruiken voor onze registratiepagina.
De CSS-klassen die in de HTML-sjabloon worden gebruikt, maken deel uit van de Bootstrap-bibliotheek die wordt gebruikt om dingen mooier te maken. Omdat dit geen zelfstudie is, zal ik niet veel over de CSS-aspecten van de vorm praten, tenzij dat nodig is.
Om de sjabloongestuurde formulierrichtlijnen te gebruiken, moeten we het FormsModule
van @ Hoekige / formulieren
en voeg het toe aan de invoer
array in app.module.ts
.
importeer FormsModule vanuit '@ angular / forms'; @ NgModule (... imports: [BrowserModule, FormsModule], ...) exportklasse AppModule
Maak vervolgens een klasse die alle eigenschappen van de gebruikersentiteit bevat. We kunnen een interface gebruiken en deze implementeren in de component of een TypeScript-klasse voor het model gebruiken.
exportklasse Gebruiker id: number; e-mail: string; // Beide wachtwoorden bevinden zich in een enkel objectwachtwoord: pwd: string; confirmPwd: string; ; geslacht: string; voorwaarden: boolean; constructor (waarden: Object = ) // Constructor-initialisatie Object.assign (this, values);
Maak nu een exemplaar van de klasse in de component SignupForm. Ik heb ook een extra eigenschap voor het geslacht aangegeven.
importeer Component, OnInit uit '@ angular / core'; // Importeer het gebruikersmodel importeren Gebruiker uit './... / Gebruiker'; @Component (selector: 'app-signup-formulier', templateUrl: './signup-form.component.html', styleUrls: ['./signup-form.component.css']) exporteer class SignupFormComponent implementeert OnInit // Eigenschap voor het geslacht privé-geslacht: tekenreeks []; // Eigenschap voor de gebruiker Privégebruiker: Gebruiker; ngOnInit () this.gender = ['Mannelijk', 'Vrouw', 'Andere']; // Maak een nieuw gebruikersobject this.user = nieuwe gebruiker (email: "", wachtwoord: pwd: "", confirm_pwd: "", geslacht: this.gender [0], terms: false);
Voor de aanmelden-form.component.html bestand, ga ik dezelfde HTML-sjabloon gebruiken die hierboven is besproken, maar met kleine wijzigingen. Het aanmeldingsformulier heeft een select veld met een lijst met opties. Hoewel dat werkt, doen we het op de hoekige manier door de lijst door te lopen met behulp van de ngFor
richtlijn.
Vervolgens willen we de formuliergegevens binden aan het gebruikersklasseobject, zodat wanneer u de registratiegegevens invoert in het formulier, er een nieuw gebruikersobject wordt gemaakt dat die gegevens tijdelijk opslaat. Op deze manier kunt u de weergave gesynchroniseerd houden met het model en dit wordt bindend genoemd.
Er zijn een aantal manieren om dit te realiseren. Laat me je eerst even voorstellen ngModel
en ngForm
.
ngForm en ngModel zijn hoekige richtlijnen die essentieel zijn voor het maken van sjabloongestuurde formulieren. Laten we beginnen met ngForm
eerste. Hier is een fragment over ngForm uit de Angular docs.
DeNgForm
richtlijn vult hethet formulier
element met extra functies. Het bevat de besturingselementen die u voor de elementen hebt gemaakt met eenngModel
richtlijn ennaam
attribuut en controleert hun eigenschappen, inclusief hun geldigheid. Het heeft ook zijn eigenGeldig
eigendom dat alleen waar is als elke ingesloten controle is geldig.
Werk eerst het formulier bij met de ngForm
richtlijn:
#signupForm
is een sjabloonreferentievariabele die verwijst naar de ngForm
richtlijn die het volledige formulier beheert. Het onderstaande voorbeeld toont het gebruik van een ngForm
referentieobject voor validatie.
Hier, signupForm.form.valid
retourneert false tenzij alle formulierelementen hun respectievelijke validatiecontroles hebben doorstaan. De knop Verzenden is uitgeschakeld totdat het formulier geldig is.
Wat betreft het binden van de sjabloon en het model, zijn er tal van manieren om dit te doen, en ngModel
heeft drie verschillende syntaxes om deze situatie aan te pakken. Zij zijn:
Laten we beginnen met de eerste.
[(NgModel)]
voert tweewegsbinding uit voor het lezen en schrijven van invoerbesturingswaarden. Als een [(NgModel)]
wordt gebruikt, neemt het invoerveld een initiële waarde van de gebonden componentklasse en werkt het opnieuw bij telkens wanneer een wijziging in de invoerbesturingswaarde wordt gedetecteerd (bij toetsaanslag en druk op de knop). De afbeelding hieronder beschrijft het bidirectionele bindproces beter.
Hier is de code voor het invoerveld voor e-mail:
[(ngModel)] = "user.email"
bindt de e-maileigenschap van de gebruiker aan de invoerwaarde. Ik heb ook een toegevoegd naam attribuut en set name = "email"
. Dit is belangrijk en u krijgt een foutmelding als u geen naamkenmerk hebt opgegeven bij het gebruik van ngModel.
Voeg ook een toe [(NgModel)]
en een uniek naam attribuut aan elk formulierelement. Uw formulier zou er nu ongeveer zo uit moeten zien:
......
De ngModelGroup
wordt gebruikt om soortgelijke formuliervelden samen te groeperen, zodat we alleen validaties op die formuliervelden kunnen uitvoeren. Omdat beide wachtwoordvelden gerelateerd zijn, zullen we ze onder een enkele ngModelGroup plaatsen. Als alles naar verwachting werkt, is het component gebonden gebruiker
eigenschap moet verantwoordelijk zijn voor het opslaan van alle formulierregelwaarden. Voeg het volgende toe na de formuletag om dit in actie te zien:
user | json
Leid de gebruikerseigenschap door de JsonPipe
om het model als JSON in de browser weer te geven. Dit is handig voor foutopsporing en logging. Je zou een JSON-uitgang zoals deze moeten zien.
De waarden stromen van het aanzicht naar het model. Hoe zit het andersom? Probeer het gebruikersobject met enkele waarden te initialiseren.
this.user = nieuwe gebruiker (// geïnitialiseerd met een aantal gegevens e-mail: "[email protected]", wachtwoord: pwd: "", confirm_pwd: "", geslacht: this.gender [0]);
En ze verschijnen automatisch in de weergave:
"email": "[email protected]", "password": "pwd": "", "confirm_pwd": "", "gender": "Male"
De binding in twee richtingen [(NgModel)]
syntaxis helpt u moeiteloos formulieren te bouwen. Het heeft echter bepaalde nadelen; daarom is er een alternatieve benadering die gebruikt ngModel
of [NgModel]
.
Wanneer ngModel
wordt gebruikt, zijn we in feite verantwoordelijk voor het bijwerken van de componenteigenschap met de invoerbesturingswaarden en omgekeerd. De invoergegevens vloeien niet automatisch over in de gebruikerseigenschap van de component.
Vervang dus alle exemplaren van [(ngModel)] = ""
met ngModel
. We zullen de naam
attribuut omdat alle drie de versies van ngModel de naam
attribuut aan het werk.
Met ngModel
, de waarde van het naamkenmerk wordt een sleutel van het ngForm-referentieobject signupForm
die we eerder hebben gemaakt. Dus bijvoorbeeld, signupForm.value.email
slaat de controlewaarde voor de e-mail-ID op.
Vervangen user | json
met signupForm.value | json
omdat daar nu alle staat is opgeslagen.
Wat als u de beginstatus van de gebonden klassencomponent moet instellen? Dat is wat de [NgModel]
doet voor jou.
Hier stromen de gegevens van het model naar het beeld. Breng de volgende wijzigingen aan in de syntaxis om one-way binding te gebruiken:
Dus welke aanpak zou je moeten kiezen? Als je gebruikt [(NgModel)]
en ngForm
samen zul je uiteindelijk twee staten hebben om te behouden-gebruiker
en signupForm.value
-en dat kan mogelijk verwarrend zijn.
"email": "[email protected]", "password": "pwd": "thisispassword", "confirm_pwd": "thisispassword", "gender": "Male" //user.value " email ":" [email protected] "," password ": " pwd ":" thisispassword "," confirm_pwd ":" thisispassword "," gender ":" Male " //signupForm.value
Daarom zal ik aanbevelen om in plaats daarvan de one-way binding-methode te gebruiken. Maar dat is iets voor u om te beslissen.
Dit zijn onze vereisten voor de validatie.
De eerste is eenvoudig. Je moet een toevoegen verplicht
validatieattribuut aan elk formulierelement zoals dit:
Los van de verplicht
attribuut, ik heb ook een nieuw geëxporteerd #email
sjabloonreferentievariabele. Dit is zodat u vanuit de sjabloon zelf toegang hebt tot de hoekbesturing van het invoervak. We zullen het gebruiken om fouten en waarschuwingen weer te geven. Gebruik nu de gedeactiveerde eigenschap van de knop om de knop uit te schakelen:
Om een beperking op e-mail toe te voegen, gebruikt u het patroonattribuut dat werkt met invoervelden. Patronen worden gebruikt om reguliere expressies zoals die hieronder te specificeren:
pattern = "[a-z0-9 ._% + -]. + @ [a-Z0-9 .-] + \ [a-z] 2,3 $"
Voor het wachtwoordveld hoeft u alleen maar een toe te voegen minlength = ""
attribuut:
Om de fouten weer te geven, ga ik de voorwaardelijke richtlijn gebruiken ngIf
op een div-element. Laten we beginnen met het invoerveld voor e-mail:
Het e-mailveld mag niet leeg zijnHet e-mailadres lijkt niet goed
Er gebeurt hier veel. Laten we beginnen met de eerste regel van het foutgedeelte.
Herinner de
email.valid
,email.invalid
,email.dirty
,email.pristine
,email.touched
,email.untouched
, enemail.errors
. De onderstaande afbeelding beschrijft elk van die eigenschappen in detail.Dus het div element met de
* ngIf
wordt alleen weergegeven als de e-mail ongeldig is. De gebruiker zal echter worden begroet met fouten over de lege invulvelden, zelfs voordat ze de kans hebben om het formulier te bewerken.Om dit scenario te voorkomen, hebben we de tweede voorwaarde toegevoegd. De fout wordt pas daarna weergegeven de besturing is bezocht of de waarde van de controle is veranderd.
De geneste div-elementen worden gebruikt voor alle gevallen van validatiefouten. We gebruiken
email.errors
om alle mogelijke validatiefouten te controleren en deze vervolgens weer te geven aan de gebruiker in de vorm van aangepaste berichten. Volg nu dezelfde procedure voor de andere formulierelementen. Hier is hoe ik de validatie voor de wachtwoorden heb gecodeerd.app / aanmelden-form / aanmelden-form.component.html
Wachtwoord moet uit meer dan 8 tekens bestaanWachtwoorden komen niet overeen Dit begint een beetje rommelig te lijken. Angular heeft een beperkte set validatorattributen:
verplicht
,minimale lengte
,maximale lengte
, enpatroon
. Om een ander scenario als dat van wachtwoordvergelijking te dekken, moet u vertrouwen op genestngIf
conditionals zoals ik hierboven deed. Of maak idealiter een aangepaste validatiefunctie die ik in het derde deel van deze serie zal behandelen.In de bovenstaande code heb ik de
anders
syntaxis die is geïntroduceerd in de nieuwste versie van Angular. Hier is hoe het werkt:Geldige inhoud ...Niet geldige inhoud ... Dien het formulier in met behulp van ngSubmit
We zijn bijna klaar met het formulier. Nu moeten we het formulier kunnen indienen en de controle van de formuliergegevens moet bijvoorbeeld worden overgedragen aan een componentmethode
onFormSubmit ()
.app / aanmelden-form / aanmelden-form.component.ts