Reactive Forms
Overview
Angular Day - 16 Giugno 2017
Michele Stieven
Freelance Web Developer & JavaScript enthusiast
Obiettivi del talk
-
Reactive Form: il concetto
-
FormControl/FormGroup/FormArray
-
FormBuilder
-
Stato e manipolazione di un form
-
Validatori (built-in/custom)
-
Demo
@angular/forms
FormsModule
Template-driven forms
ReactiveFormsModule
Model-driven forms
import { ReactiveFormsModule } from "@angular/forms";
@NgModule({
...
imports: [
ReactiveFormsModule
]
})
...
Reactive Style
Spostamento della logica di un form dal template al controller.
-
#f="ngForm"
-
ngModel
-
required
-
...
NO
Template-driven
<form #f="ngForm" (ngSubmit)="myMethod($event)">
<input type="text"
[(ngModel)]="user.name" required>
<input type="text"
[(ngModel)]="user.surname" required>
</form>
Model-driven
<form [formGroup]="user" (ngSubmit)="myMethod()">
<input type="text"
formControlName="name">
<input type="text"
formControlName="surname">
</form>
... Perché?
Validazioni
Pulizia
Controlli custom
Testing
Componenti principali
FormControl
singolo controllo (input, select, textarea...)
FormGroup
gruppo di controlli
FormArray
array di controlli
AbstractControl
classe generica
FormControl
name = new FormControl('Mario');
name = new FormControl({
value: 'Mario',
disabled: true
});
Oggetto
name = new FormControl(
'Mario',
Validators.required
);
Validatore...
name = new FormControl(
'Mario',
[
Validators.required,
Validators.minLength(4)
]
);
...o array di Validatori
FormGroup
myForm = new FormGroup({
name: new FormControl('Mario'),
surname: new FormControl('Rossi')
});
FormArray
cities = new FormArray([
new FormControl('Verona'),
new FormControl('Milano'),
new FormControl('Roma')
]);
FormArray utilities
-
at
-
push
-
insert
-
removeAt
-
setControl
-
length
La classe ci mette a disposizione dei metodi per interagire con l'array:
AbstractControl
AbstractControl
-
value
-
parent
-
status
-
valid
-
invalid
-
pending
-
disabled
-
enabled
-
errors
Ogni controllo, estendendo questa classe, ci mette a disposizione queste proprietà:
Demo
FormGroup
FormControl
FormControl
FormArray
Custom Control
FormBuilder
FormBuilder è un servizio per semplificare la costruzione dei Reactive Form.
import { FormBuilder } from '@angular/forms';
@Component({
...
})
export class AppComponent {
constructor(private fb: FormBuilder){ }
}
myForm = this.fb.group({
name: 'Mario',
surname: 'Rossi',
phones: this.fb.array([])
});
myForm = new FormGroup({
name: new FormControl('Mario'),
surname: new FormControl('Rossi'),
phones: new FormArray([])
});
Stati di un form/controllo
Dirty
Touched
Valid
Diventa true nel momento in cui l'utente clicca (focus) ed esce dal controllo (blur). Il suo opposto è untouched.
Diventa true nel momento in cui cambia il valore del controllo. Il suo opposto è pristine.
Diventa true se il controllo passa tutte le validazioni. Il suo opposto è invalid.
API Utilities
myForm.status
valid | invalid | pending | disabled
myForm.get('name')
myForm.controls.name
myForm.errors myForm.get('name').errors
{ ValidationErrors }
myForm.hasError('myError')
true | false
SetValue()
vs
PatchValue()
myForm = this.fb.group({
name: '',
surname: ''
});
setValue
patchValue
myForm.patchValue({
name: 'Mario'
});
myForm.patchValue({
name: 'Mario',
surname: 'Rossi'
});
myForm.setValue({
name: 'Mario'
});
myForm.setValue({
name: 'Mario',
surname: 'Rossi'
});
myForm.patchValue({
name: 'Mario',
surname: 'Rossi',
age: 18
});
myForm.setValue({
name: 'Mario',
surname: 'Rossi',
age: 18
});
myForm.reset()
- Assegna il valore null ai controlli del form
- Il form/controllo torna ad essere untouched e pristine
- Possiamo resettare il form ad un valore specifico
- Può essere applicato ai singoli controlli
Cosa fa:
Cosa non fa:
- Non rimuove i controlli di un FormArray, li imposta a null
Validatori
Built-in validators
import { Validators } from '@angular/forms'
Validators.required
Validators.minLength()
Validators.maxLength()
Validators.pattern()
this.myForm = this.fb.group({
name: ['', Validators.required],
surname: ['', Validators.required],
age: '18',
phones: this.fb.array([])
});
Custom Validators
Un validatore custom è semplicemente una funzione!
Di tipo ValidatorFn
function customValidator(control: AbstractControl) {
if (...) {
return {Error: control.value}
}
return null;
};
function customValidator(myParams): ValidatorFn {
return (control: AbstractControl) => {
if (...) {
// Do something with myParams
return {Error: control.value}
}
return null;
};
}
Validatore con parametri
export function nameValidator(param: string)
name: [
'',
[
Validators.required,
nameValidator('Michele')
]
]
import { AbstractControl, ValidatorFn } from '@angular/forms';
export function nameValidator(param): ValidatorFn {
return (control: AbstractControl) => {
if (control.value === param) {
return {nameError: param}
}
return null;
};
}
FormGroup Validators
Possiamo creare dei validatori custom per effettuare validazioni di più controlli all'interno di un FormGroup.
cred = {
name: 'Mario',
surname: 'Rossi'
};
[...]
this.myForm = this.fb.group({
name: '',
surname: ''
},
{
validator: customCredentialsValidator(this.cred)
});
export function customCredentialsValidator(cred) {
return (control: AbstractControl) => {
const name = control.get('name');
const surname = control.get('surname');
[...]
};
};
...THE END?
Q&A
Ultima slide!
Ti è piaciuta la presentazione?
Ricorda di dare un voto al mio talk e all'Angular Day in generale!
Grazie!
Angular Dev Ita
JavaScript Dev Ita
Reactive Forms Overview
By Michele Stieven
Reactive Forms Overview
Angular Day 2017 - 16/06/2017
- 246