Dit is het tweede deel van de serie over Inleiding tot Formulieren in Angular 4. In het eerste deel hebben we een formulier gemaakt met behulp van de sjabloongestuurde aanpak. We gebruikten richtlijnen zoals ngModel
, ngModelGroup
en ngForm
om de formulierelementen op te laden. In deze zelfstudie gaan we een andere benadering gebruiken voor het bouwen van vormen, de reactieve manier.
Reactieve vormen hebben een andere benadering dan die van de sjabloongestuurde vormen. Hier maken en initialiseren we de vorm controle objecten in onze componentklasse. Het zijn tussenliggende objecten die de status van het formulier behouden. We zullen ze dan binden aan de vorm besturingselementen in de sjabloon.
Het formulierbesturingsobject luistert naar elke wijziging in de invoerbesturingswaarden en deze worden onmiddellijk weerspiegeld in de staat van het object. Omdat de component directe toegang heeft tot de gegevensmodelstructuur, kunnen alle wijzigingen worden gesynchroniseerd tussen het gegevensmodel, het formulierbesturingsobject en de invoerbesturingswaarden.
Praktisch gesproken, als we een formulier bouwen voor het bijwerken van het gebruikersprofiel, is het datamodel het gebruikersobject dat is opgehaald van de server. Volgens afspraak wordt dit vaak opgeslagen in de gebruikerseigenschap van de component (this.user
). Het formulierbesturingsobject of het formuliermodel zal worden gebonden aan de eigenlijke formulierbesturingselementen van de sjabloon.
Beide modellen moeten vergelijkbare structuren hebben, zelfs als ze niet identiek zijn. De invoerwaarden mogen echter niet rechtstreeks in het gegevensmodel vloeien. De afbeelding beschrijft hoe de gebruikersinvoer vanuit de sjabloon zijn weg vindt naar het formuliermodel.
Laten we beginnen.
U hoeft deel 1 van deze serie niet te hebben gevolgd, want deel twee is logisch. Als u echter nog geen ervaring heeft met formulieren in Angular, raad ik u aan de sjabloongestuurde strategie te doorlopen. De code voor dit project is beschikbaar op mijn GitHub-repository. Zorg ervoor dat u zich in de juiste tak bevindt en download vervolgens de zip of, als alternatief, de repo om het formulier in actie te zien klonen.
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 component voor de SignupForm
of maak er handmatig een.
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 een Reactief formulier te maken, moet u het ReactiveFormsModule
van @ Hoekige / formulieren
en voeg het toe aan de invoerarray in app.module.ts.
// Importeer ReactiveFormsModule import ReactiveFormsModule uit '@ angular / forms'; @ NgModule (... // Voeg de module toe aan de invoer Array-import: [BrowserModule, ReactiveFormsModule ...) exportklasse AppModule
Maak vervolgens een gebruikersmodel voor het registratieformulier. We kunnen een klasse of een interface gebruiken om het model te maken. Voor deze zelfstudie ga ik een klasse exporteren met de volgende eigenschappen.
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 het gebruikersmodel in de SignupForm
bestanddeel.
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 // Geslachtlijst voor het geselecteerde besturingselement private genderList: string []; // Eigenschap voor de gebruiker Privégebruiker: Gebruiker; ngOnInit () this.genderList = ['Mannelijk', 'Vrouw', 'Andere'];
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.
Opmerking: mogelijk krijgt u een foutmelding Geen provider voor ControlContainer. De fout verschijnt wanneer een component een heeft
We hebben een component, een model en een formuliersjabloon bij de hand. Wat nu? Het is tijd om onze handen vuil te maken en kennis te maken met de API's die u nodig hebt om reactieve vormen te creëren. Dit bevat FormControl
en FormGroup
.
Terwijl u formulieren bouwt met de strategie voor reactieve vormen, ziet u de instructies ngModel en ngForm niet. In plaats daarvan gebruiken we de onderliggende API FormControl en FormGroup.
Een FormControl is een instructie die wordt gebruikt om een FormControl-instantie te maken die u kunt gebruiken om de status van een bepaald formulierelement en de bijbehorende validatiestatus bij te houden. Dit is hoe FormControl werkt:
/ * Import FormControl eerst * / import FormControl vanuit '@ angular / forms'; / * Voorbeeld van het maken van een nieuwe FormControl-instantie * / exportklasse SignupFormComponent email = new FormControl ();
e-mail
is nu een FormControl-instantie en u kunt het als volgt binden aan een invoerbesturingselement in uw sjabloon:
Inschrijven
Het sjabloonformulierelement is nu gebonden aan de FormControl-instantie in het onderdeel. Wat dat betekent, is dat elke verandering in de invoerbesturingswaarde aan het andere uiteinde wordt weerspiegeld.
Een FormControl-constructor accepteert drie argumenten - een beginwaarde, een reeks synchronisatievalidators en een reeks asynchrone validators - en zoals u misschien al hebt geraden, zijn ze allemaal optioneel. We zullen hier de eerste twee argumenten behandelen.
importeer Validators uit '@ angular / forms'; ... / * FormControl met beginwaarde en een validator * / email = nieuwe FormControl ('[email protected] ', Validators.required);
Angular heeft een beperkte set ingebouwde validators. De populaire validatiemethoden omvatten Validators.required
, Validators.minLength
, Validators.maxlength
, en Validators.pattern
. Om ze te gebruiken, moet u echter eerst de Validator API importeren.
Voor ons aanmeldingsformulier hebben we meerdere invoerbesturingsvelden (voor e-mail en wachtwoord), een selectieveld en een selectievakje. In plaats van een individu te creëren FormControl
objecten, zou het niet logischer zijn om al deze te groeperen FormControl
s onder een enkele entiteit? Dit is nuttig omdat we nu de waarde en de geldigheid van alle sub-FormControl-objecten op één plaats kunnen volgen. Dat is wat FormGroup
is voor. Dus we zullen een bovenliggende FormGroup registreren met meerdere onderliggende FormControls.
Als u een FormGroup wilt toevoegen, moet u deze eerst importeren. Formuleer vervolgens signupForm als een klasseneigenschap en initialiseer het als volgt:
// Importeer de API voor het bouwen van een formulierimport FormControl, FormGroup, Validators uit '@ angular / forms'; export class SignupFormComponent implementeert OnInit genderList: String []; signupForm: FormGroup; ... ngOnInit () this.genderList = ['Male', 'Female', 'Others']; this.signupForm = nieuwe FormGroup (email: new FormControl (", Validators.required), pwd: new FormControl (), confirmPwd: new FormControl (), gender: new FormControl (), terms: new FormControl ())
Bind het FormGroup-model als volgt aan de DOM: