Questa è la seconda parte della serie su Introduction to Forms in Angular 4. Nella prima parte, abbiamo creato un modulo utilizzando l'approccio basato su template. Abbiamo usato direttive come ngModel
, ngModelGroup
e ngForm
per potenziare gli elementi del modulo. In questo tutorial, adotteremo un approccio diverso alla costruzione delle forme, la via reattiva.
Le forme reattive adottano un approccio diverso rispetto a quello delle forme basate su template. Qui, creiamo e inizializziamo il forma oggetti di controllo nella nostra classe componente. Sono oggetti intermedi che mantengono lo stato della forma. Li legheremo quindi al forma elementi di controllo nel modello.
L'oggetto di controllo del modulo ascolta qualsiasi modifica nei valori di controllo di input e si riflettono immediatamente nello stato dell'oggetto. Poiché il componente ha accesso diretto alla struttura del modello dati, tutte le modifiche possono essere sincronizzate tra il modello dati, l'oggetto controllo modulo e i valori di controllo di input.
In pratica, se stiamo costruendo un modulo per l'aggiornamento del profilo utente, il modello dati è l'oggetto utente recuperato dal server. Per convenzione, questo è spesso memorizzato all'interno della proprietà dell'utente del componente (this.user
). L'oggetto di controllo del modulo o il modello di modulo saranno associati agli elementi di controllo del modulo effettivo del modello.
Entrambi questi modelli dovrebbero avere strutture simili, anche se non sono identici. Tuttavia, i valori di input non devono essere trasferiti direttamente nel modello di dati. L'immagine descrive come l'input dell'utente dal modello raggiunge il modello di modulo.
Iniziamo.
Non è necessario aver seguito la prima parte di questa serie, perché la seconda parte abbia senso. Tuttavia, se sei nuovo ai moduli in Angular, ti consiglio vivamente di passare attraverso la strategia basata sui modelli. Il codice per questo progetto è disponibile sul mio repository GitHub. Assicurati di essere nel ramo giusto e poi scarica lo zip o, in alternativa, clonare il repository per vedere il modulo in azione.
Se preferisci ripartire da zero, assicurati di aver installato la CLI Angolare. Utilizzare il ng
comando per generare un nuovo progetto.
$ ng nuovo SignupFormProject
Quindi, generare un nuovo componente per il SignupForm
o crearne uno manualmente.
ng genera il componente SignupForm
Sostituisci il contenuto di app.component.html con questo:
Ecco la struttura della directory per src / directory. Ho rimosso alcuni file non essenziali per semplificare le cose.
. ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── modulo di iscrizione │ │ ├ ── 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
Come puoi vedere, una directory per il SignupForm
componente è stato creato automaticamente. Ecco dove andrà la maggior parte del nostro codice. Ho anche creato un nuovo User.ts
per memorizzare il nostro modello utente.
Prima di immergerci nel modello di componente reale, abbiamo bisogno di avere un'idea astratta di ciò che stiamo costruendo. Quindi ecco la struttura del modulo che ho nella mia mente. Il modulo di iscrizione avrà diversi campi di input, un elemento select e un elemento checkbox.
Ecco il modello HTML che utilizzeremo per la nostra pagina di registrazione.
Le classi CSS utilizzate nel modello HTML fanno parte della libreria Bootstrap utilizzata per rendere le cose carine. Poiché non si tratta di un tutorial di progettazione, non parlerò molto degli aspetti CSS del modulo, a meno che non sia necessario.
Per creare un modulo Reattivo, è necessario importare il file ReactiveFormsModule
a partire dal @ angolari / forme
e aggiungilo alla matrice delle importazioni in app.module.ts.
// Importa ReactiveFormsModule import ReactiveFormsModule da '@ angular / forms'; @NgModule (... // Aggiungi il modulo alle importazioni dell'Array delle importazioni: [BrowserModule, ReactiveFormsModule ...) Esporta classe AppModule
Quindi, creare un modello utente per il modulo di registrazione. Possiamo usare una classe o un'interfaccia per creare il modello. Per questo tutorial, ho intenzione di esportare una classe con le seguenti proprietà.
classe di esportazione Utente id: numero; email: string; // Entrambe le password sono in una password per un singolo oggetto: pwd: string; confirmPwd: string; ; genere: stringa; termini: booleano; costruttore (valori: Object = ) // Inizializzazione costruttore Object.assign (this, values);
Ora, crea un'istanza del modello Utente in SignupForm
componente.
import Component, OnInit da '@ angular / core'; // Importa l'importazione del modello utente Utente da './... / Utente'; @Component (selector: 'app-signup-form', templateUrl: './signup-form.component.html', styleUrls: ['./signup-form.component.css']) classe di esportazione SignupFormComponent implementa OnInit // Elenco di genere per l'elemento di controllo select private genderList: string []; // Proprietà per l'utente privato dell'utente: Utente; ngOnInit () this.genderList = ['Male', 'Female', 'Others'];
Per il iscrizione-form.component.html file, ho intenzione di utilizzare lo stesso modello HTML discusso sopra, ma con modifiche minori. Il modulo di iscrizione ha un campo di selezione con un elenco di opzioni. Anche se funziona, lo faremo in modo angolare scorrendo la lista usando il comando ngFor
direttiva.
Nota: potresti ricevere un errore che dice Nessun provider per ControlContainer. L'errore appare quando un componente ha un
Abbiamo a disposizione un componente, un modello e un modello di modulo. E adesso? È tempo di sporcarci le mani e di conoscere le API necessarie per creare moduli reattivi. Ciò comprende FormControl
e FormGroup
.
Durante la costruzione di moduli con la strategia delle forme reattive, non si incontrano le direttive ngModel e ngForm. Al contrario, utilizziamo l'API FormControl e FormGroup sottostante.
Un FormControl è una direttiva utilizzata per creare un'istanza FormControl che è possibile utilizzare per tenere traccia dello stato di un particolare elemento del modulo e del relativo stato di convalida. Ecco come funziona FormControl:
/ * Importa FormControl prima * / import FormControl da '@ angular / forms'; / * Esempio di creazione di una nuova istanza di FormControl * / export class SignupFormComponent email = new FormControl ();
e-mail
è ora un'istanza FormControl e puoi associarla a un elemento di controllo di input nel modello come segue:
Iscriviti
L'elemento del modulo template è ora associato all'istanza FormControl nel componente. Ciò significa che qualsiasi modifica al valore del controllo di input viene riflessa all'altra estremità.
Un costruttore di FormControl accetta tre argomenti, un valore iniziale, una matrice di validatori di sincronizzazione e un array di validatori asincroni e, come si potrebbe immaginare, sono tutti facoltativi. Qui tratteremo i primi due argomenti.
import Validators da '@ angular / forms'; ... / * FormControl con valore iniziale e un validatore * / email = nuovo FormControl ('[email protected] ', Validators.required);
Angular ha un set limitato di validatori integrati. I metodi di validazione popolari includono Validators.required
, Validators.minLength
, Validators.maxlength
, e Validators.pattern
. Tuttavia, per utilizzarli, devi prima importare l'API Validator.
Per il nostro modulo di registrazione, abbiamo più campi di controllo di input (per e-mail e password), un campo di selezione e un campo checkbox. Piuttosto che creare individui FormControl
oggetti, non avrebbe più senso raggruppare tutti questi FormControl
s sotto un'unica entità? Questo è utile perché ora possiamo tenere traccia del valore e della validità di tutti gli oggetti sub-FormControl in un unico punto. Questo è ciò che FormGroup
è per. Quindi registreremo un FormGroup padre con più FormControls secondari.
Per aggiungere un FormGroup, importalo prima. Quindi, dichiarare signupForm come proprietà della classe e inizializzarlo come segue:
// Importa l'API per creare un modulo import FormControl, FormGroup, Validators da '@ angular / forms'; export class SignupFormComponent implementa OnInit genderList: String []; signupForm: FormGroup; ... ngOnInit () this.genderList = ['Male', 'Female', 'Others']; this.signupForm = new FormGroup (email: nuovo FormControl (", Validators.required), pwd: new FormControl (), confirmPwd: new FormControl (), gender: new FormControl (), termini: new FormControl ())
Associare il modello FormGroup al DOM come segue: