Els formularis reactius en Angular proporcionen una manera més robusta i escalable de gestionar formularis complexos. A diferència dels formularis basats en plantilles, els formularis reactius es defineixen i gestionen completament en el codi TypeScript, oferint un major control i flexibilitat.
Contingut
Introducció als formularis reactius
Els formularis reactius es basen en un model de dades explícit i immutable, el que significa que cada canvi en el formulari crea un nou objecte de model. Això facilita la gestió de l'estat del formulari i la seva validació.
Avantatges dels formularis reactius
- Control total: Tots els aspectes del formulari es defineixen en el codi TypeScript.
- Validació avançada: És més fàcil implementar validacions complexes i personalitzades.
- Escalabilitat: Ideal per a formularis grans i complexos.
- Testabilitat: Els formularis reactius són més fàcils de provar unitàriament.
Configuració del mòdul de formularis reactius
Abans de començar a treballar amb formularis reactius, hem d'importar el mòdul ReactiveFormsModule en el nostre mòdul Angular.
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
// altres mòduls
ReactiveFormsModule
],
// altres configuracions
})
export class AppModule { }Creació d'un formulari reactiu
Pas 1: Definir el formulari en el component TypeScript
Primer, hem de crear una instància de FormGroup i definir els controls del formulari utilitzant FormControl.
import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html'
})
export class ReactiveFormComponent {
myForm: FormGroup;
constructor() {
this.myForm = new FormGroup({
name: new FormControl(''),
email: new FormControl(''),
password: new FormControl('')
});
}
onSubmit() {
console.log(this.myForm.value);
}
}Pas 2: Vincular el formulari en la plantilla HTML
Utilitzem la directiva formGroup per vincular el formulari definit en el component TypeScript amb la plantilla HTML.
<form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <label for="name">Name:</label> <input id="name" formControlName="name"> <label for="email">Email:</label> <input id="email" formControlName="email"> <label for="password">Password:</label> <input id="password" type="password" formControlName="password"> <button type="submit">Submit</button> </form>
Validació de formularis reactius
Validació bàsica
Podem afegir validacions bàsiques utilitzant els validators integrats d'Angular.
import { Validators } from '@angular/forms';
this.myForm = new FormGroup({
name: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(6)])
});Mostrar missatges d'error
Podem mostrar missatges d'error en la plantilla HTML basant-nos en l'estat de validació dels controls.
<div *ngIf="myForm.get('name').invalid && myForm.get('name').touched">
<small *ngIf="myForm.get('name').errors.required">Name is required.</small>
</div>
<div *ngIf="myForm.get('email').invalid && myForm.get('email').touched">
<small *ngIf="myForm.get('email').errors.required">Email is required.</small>
<small *ngIf="myForm.get('email').errors.email">Invalid email format.</small>
</div>
<div *ngIf="myForm.get('password').invalid && myForm.get('password').touched">
<small *ngIf="myForm.get('password').errors.required">Password is required.</small>
<small *ngIf="myForm.get('password').errors.minlength">Password must be at least 6 characters long.</small>
</div>Exemple pràctic
Component TypeScript
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html'
})
export class ReactiveFormComponent {
myForm: FormGroup;
constructor() {
this.myForm = new FormGroup({
name: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(6)])
});
}
onSubmit() {
if (this.myForm.valid) {
console.log(this.myForm.value);
} else {
console.log('Form is invalid');
}
}
}Plantilla HTML
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label for="name">Name:</label>
<input id="name" formControlName="name">
<div *ngIf="myForm.get('name').invalid && myForm.get('name').touched">
<small *ngIf="myForm.get('name').errors.required">Name is required.</small>
</div>
<label for="email">Email:</label>
<input id="email" formControlName="email">
<div *ngIf="myForm.get('email').invalid && myForm.get('email').touched">
<small *ngIf="myForm.get('email').errors.required">Email is required.</small>
<small *ngIf="myForm.get('email').errors.email">Invalid email format.</small>
</div>
<label for="password">Password:</label>
<input id="password" type="password" formControlName="password">
<div *ngIf="myForm.get('password').invalid && myForm.get('password').touched">
<small *ngIf="myForm.get('password').errors.required">Password is required.</small>
<small *ngIf="myForm.get('password').errors.minlength">Password must be at least 6 characters long.</small>
</div>
<button type="submit">Submit</button>
</form>Exercicis pràctics
Exercici 1: Formulari de registre
Crea un formulari de registre amb els següents camps:
- Nom d'usuari (obligatori)
- Correu electrònic (obligatori i format d'email)
- Contrasenya (obligatori i mínim 8 caràcters)
- Confirmació de contrasenya (obligatori i ha de coincidir amb la contrasenya)
Solució
Component TypeScript
import { Component } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-register-form',
templateUrl: './register-form.component.html'
})
export class RegisterFormComponent {
registerForm: FormGroup;
constructor() {
this.registerForm = new FormGroup({
username: new FormControl('', [Validators.required]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(8)]),
confirmPassword: new FormControl('', [Validators.required])
}, this.passwordMatchValidator);
}
passwordMatchValidator(form: FormGroup) {
return form.get('password').value === form.get('confirmPassword').value
? null : { 'mismatch': true };
}
onSubmit() {
if (this.registerForm.valid) {
console.log(this.registerForm.value);
} else {
console.log('Form is invalid');
}
}
}Plantilla HTML
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<label for="username">Username:</label>
<input id="username" formControlName="username">
<div *ngIf="registerForm.get('username').invalid && registerForm.get('username').touched">
<small *ngIf="registerForm.get('username').errors.required">Username is required.</small>
</div>
<label for="email">Email:</label>
<input id="email" formControlName="email">
<div *ngIf="registerForm.get('email').invalid && registerForm.get('email').touched">
<small *ngIf="registerForm.get('email').errors.required">Email is required.</small>
<small *ngIf="registerForm.get('email').errors.email">Invalid email format.</small>
</div>
<label for="password">Password:</label>
<input id="password" type="password" formControlName="password">
<div *ngIf="registerForm.get('password').invalid && registerForm.get('password').touched">
<small *ngIf="registerForm.get('password').errors.required">Password is required.</small>
<small *ngIf="registerForm.get('password').errors.minlength">Password must be at least 8 characters long.</small>
</div>
<label for="confirmPassword">Confirm Password:</label>
<input id="confirmPassword" type="password" formControlName="confirmPassword">
<div *ngIf="registerForm.errors?.mismatch && registerForm.get('confirmPassword').touched">
<small>Passwords do not match.</small>
</div>
<button type="submit">Register</button>
</form>Conclusió
Els formularis reactius en Angular proporcionen una manera poderosa i flexible de gestionar formularis complexos. Amb un control total sobre l'estat del formulari i la seva validació, els formularis reactius són ideals per a aplicacions que requereixen una gestió avançada de formularis. Practicar amb exemples i exercicis és clau per dominar aquesta tècnica.
Curs d'Angular 2+
Mòdul 1: Introducció a Angular
- Què és Angular?
- Configuració de l'entorn de desenvolupament
- La teva primera aplicació Angular
- Arquitectura d'Angular
Mòdul 2: Conceptes bàsics de TypeScript
- Introducció a TypeScript
- Variables i tipus de dades en TypeScript
- Funcions i funcions fletxa
- Classes i interfícies
Mòdul 3: Components i plantilles
Mòdul 4: Directives i pipes
Mòdul 5: Serveis i injecció de dependències
Mòdul 6: Enrutament i navegació
Mòdul 7: Formularis en Angular
Mòdul 8: Client HTTP i observables
- Introducció al client HTTP
- Realització de sol·licituds HTTP
- Gestió de respostes HTTP
- Ús d'observables
