back to top

Form in Angular: due differenti approcci Template Driven e Reactive Form

In questa lezione inizieremo a parlare dei due diversi approcci forniti da Angular per lavorare con i form e vedremo in che modo è possibile acquisire delle informazioni immesse da un utente, validare ciascun campo di input o l’intero form e presentare dei messaggi in caso di errore.

Esistono due diversi modi per creare e gestire dei form in Angular ognuno dei quali presenta dei vantaggi e degli aspetti negativi.

Esistono infatti due distinte tipologie di form che prendono il nome di:

  • Template-driven form è il metodo per certi versi più semplice, adatto principalmente per creare dei form di pochi campi che non richiedono elaborazioni complesse. Come suggerisce lo stesso nome, nel realizzare e configurare questo tipo di form svolgeremo la maggior parte del lavoro all’interno del template facendo uso di diversi tipi di direttive anche per la validazione dei campi.
  • Reactive forms (o Model-driven forms) permettono di costruire dei form più flessibili e riutilizzabili. Al contrario della precedente categoria, la logica del form viene spostata dal template al componente stesso così come tutte le istruzioni per la validazione dei vari campi. I moduli costruiti con questa tecnica sono anche più semplici da testare.

Iniziamo a vedere come creare lo stesso form utilizzando prima uno e poi l’altro approccio in modo da evidenziare quali sono le differenze fra i due metodi.

Immaginiamo quindi di voler creare un form per prenotare un appuntamento presso un determinato ufficio così come mostrato nell’immagine sottostante.

esempio form in Angular

Come utilizzare bootstrap in Angular

Anche se non è direttamente collegato con l’argomento che stiamo trattando, apriamo una breve parentesi e vediamo come includere un front-end framework come Bootstrap (includeremo solo i fogli di stile) all’interno del nostro progetto in modo da semplificare la disposizione degli elementi del form all’interno della nostra applicazione.

Dopo aver inizializzato un nuovo progetto con il comando ng new, procediamo all’installazione di Bootstrap.

npm install --save bootstrap

Aggiorniamo poi il file angular.json andando a modificare l’oggetto assegnato alla proprietà ‘projects.my-angular-app.styles’, ovvero quella relativa all’applicazione di default del workspace.

"styles": [
  "src/styles.css",
  "node_modules/bootstrap/dist/css/bootstrap.min.css"
]

Così facendo segnaliamo ad Angular di aggiungere altri fogli di stile a livello globale oltre a quello predefinito

Con questi pochi passaggi abbiamo reso disponibili le regole presenti nei fogli di stile di Bootstrap in tutta la nostra applicazione.

I Template-driven form

Dopo aver visto come includere Bootstrap nella nostra applicazione, torniamo a parlare dei form e iniziamo a vedere come crearne uno utilizzando l’approccio Template-driven.

All’interno della nostra applicazione iniziamo a modificare il file app.component.ts come riportato sotto.

import { Component } from '@angular/core';

@Component({
  selector: 'simple-root',
  template: '<simple-template-driven-form></simple-template-driven-form>'
})
export class AppComponent { }

Creiamo quindi un nuovo componente TemplateDrivenFormComponent.

ng generate component template-driven-form --no-spec
tree src/app
  src/app
  ├── app.component.ts
  ├── app.module.ts
  └── template-driven-form
      ├── template-driven-form.component.css
      ├── template-driven-form.component.html
      └── template-driven-form.component.ts
  
  1 directory, 5 files

A questo punto possiamo iniziare ad inserire nel file template-driven-form.component.html il codice HTML da cui partiremo per realizzare un modulo simile a quello visto nell’immagine riportata sopra.

<form novalidate>
  <div class="form-row">
    <div class="col-md-4 mb-2">
      <label for="name">Nome</label>
      <input type="text"
        class="form-control"
        id="name" 
        name="name"
        placeholder="Inserisci il tuo nome">
    </div>
    <div class="col-md-4 mb-2">
      <label for="mail">E-mail</label>
      <input type="email"
        class="form-control"
        id="mail" 
        name="mail"
        placeholder="Inserisci la tua e-mail">
    </div>
    <div class="col-md-4 mb-2">
      <label for="dayOfTheWeek">Giorno della settimana</label>
      <select name="dayOfTheWeek" id="dayOfTheWeek" class="form-control">
        <option value="0">Luned&igrave;</option>
        <option value="1">Marted&igrave;</option>
        <option value="2">Mercoled&igrave;</option>
        <option value="3">Gioved&igrave;</option>
        <option value="4">Venerd&igrave;</option>
      </select>
    </div>
  </div>
  <div class="form-row mt-3 mb-3">
    <div class="form-check form-check-inline">
      <input type="radio"
        name="office"
        id="office-A"
        class="form-check-input"
        value="ufficio_A">
      <label for="office" class="form-check-label">Ufficio A</label>
    </div>
    <div class="form-check form-check-inline">
      <input type="radio"
        name="office"
        id="office-B"
        class="form-check-input"
        value="ufficio_B">
      <label for="office" class="form-check-label">Ufficio B</label>
    </div>
    <div class="form-check form-check-inline">
      <input type="radio"
        name="office"
        id="office-C"
        class="form-check-input"
        value="ufficio_C">
      <label for="office" class="form-check-label">Ufficio C</label>
    </div>
  </div>
  <div class="form-row mt-3 mb-3">
    <div class="form-check form-check-inline">
      <input type="checkbox"
        name="application1"
        id="application-1"
        class="form-check-input"
        value="richiesta_1">
      <label for="application" class="form-check-label">Richiesta 1</label>
    </div>
    <div class="form-check form-check-inline">
      <input type="checkbox"
        name="application2"
        id="application-2"
        class="form-check-input"
        value="richiesta_2">
      <label for="application" class="form-check-label">Richiesta 2</label>
    </div>
    <div class="form-check form-check-inline">
      <input type="checkbox"
        name="application3"
        id="application-3"
        class="form-check-input"
        value="richiesta_3">
      <label for="application" class="form-check-label">Richiesta 3</label>
    </div>
  </div>
  <div class="form-row">
    <button type="submit" class="btn btn-primary">Prenota</button>
  </div>
</form>

Siamo pronti ora ad importare il modulo FormsModule che contiene le direttive necessarie per creare un form seguendo l’approccio Template-driven. Andiamo allora a modificare il file app.module.ts e, dopo aver importato il modulo FormsModule da @angular/forms, aggiungiamolo all’array imports.

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // 1
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { 
  TemplateDrivenFormComponent 
} from './template-driven-form/template-driven-form.component';

@NgModule({
  declarations: [
    AppComponent,
    TemplateDrivenFormComponent
  ],
  imports: [
    BrowserModule,
    FormsModule // 2
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Una delle direttive presenti in FormsModule che andremo ad usare è NgForm la quale presenta un selettore corrispondente al tag HTML <form>. Per questo motivo non appena viene importato il modulo FormsModule, la direttiva NgForm viene automaticamente applicata a tutti i <form> dell’applicazione.

Risulta estremamente utile poter accedere all’istanza di ngForm associata ad un particolare form per poter valutare non solo il valore dei singoli campi che lo costituiscono ma anche il loro stato corrente così come quello dell’intero modulo. A tale scopo possiamo assegnare ngForm ad una Template reference variable come mostrato sotto.

<form #form="ngForm">
  <!-- Resto del form riportato sopra -->
</form>

La direttiva ngForm crea in automatico un oggetto di tipo FormGroup per l’intero <form>. Tale oggetto presenta numerose proprietà contenenti le informazioni relative allo stato corrente del form, ma possiede anche una proprietà value che mantiene il valore dei diversi campi del form.

Se provassimo ad ispezionare ora tale proprietà, otterremo un oggetto vuoto perché, nonostante la direttiva ngForm venga automaticamente associata ai vari form dell’applicazione, quest’ultima non è in grado di rilevare tutti i diversi campi di input presenti all’interno del <form> se non vengono esplicitamente segnalati.

Per registrare un campo di input e indicare alla direttiva ngForm che dovrà tenere traccia del suo stato, dovremo utilizzare la direttiva NgModel.

La direttiva NgModel crea un oggetto di tipo FormControl che permette di mantenere le informazioni relative a ciascun elemento di <input> a cui viene associata.

Per ciascun elemento di input a cui è stato applicata la direttiva ngModel verrà poi creata una coppia chiave-valore all’interno dell’oggetto FormGroup che li contiene in modo che la chiave corrisponda al valore dell’attributo name del campo e il valore sia proprio un oggetto di tipo FormControl.

Per esempio possiamo aggiungere la direttiva ngModel al campo di input avente attributo name pari a "name".

<input type="text"
  class="form-control"
  id="name" 
  name="name"
  placeholder="Inserisci il tuo nome"
  ngModel>

E se analizziamo il contenuto dell’oggetto FormGroup associato all’intero <form>, vedremo che è presente una proprietà form.control che presenta un riferimento ad un oggetto come quello mostrato sotto.

{
  "name": [FormControl Object]
}

All’interno dell’oggetto FormGroup relativo all’intero <form> possiamo anche accedere alla proprietà value che sarà un oggetto avente come chiave "name" e come valore quello del campo di input.

{
  "name": ""
}

Ogni volta che il valore del campo di input varia, tale proprietà viene modificata per riflettere gli ultimi aggiornamenti come possiamo notare nell’immagine sottostante in cui mostriamo il funzionamento del form creato dopo aver inserito nella pagina, tramite interpolazione, il valore di form.value.

<pre><code>{{ form.value | json }}</code></pre>

Ottimizzazione del Template-driven form grazie alle direttive NgForm e NgModel

A questo punto possiamo procedere a modificare il nostro form in modo da registrare i diversi campi di input con la direttiva ngForm e utilizzare le conoscenze acquisite nel corso di queste lezioni per semplificare il codice. In particolar modo potremo sfruttare la direttiva *ngFor come mostrato sotto.

<form novalidate #form="ngForm">
  <div class="form-row">
    <div class="col-md-4 mb-2">
      <label for="name">Nome</label>
      <input type="text"
        class="form-control"
        id="name"
        name="name"
        placeholder="Inserisci il tuo nome"
        [(ngModel)]="model.name">
    </div>
    <div class="col-md-4 mb-2">
      <label for="mail">E-mail</label>
      <input type="email"
        class="form-control"
        id="mail"
        name="mail"
        placeholder="Inserisci la tua e-mail"
        [(ngModel)]="model.mail">
    </div>
    <div class="col-md-4 mb-2">
      <label for="dayOfTheWeek">Giorno della settimana</label>
      <select
        name="dayOfTheWeek"
        id="dayOfTheWeek"
        class="form-control"
        [(ngModel)]="model.dayOfTheWeek">
        <option *ngFor="let day of daysOfTheWeek" 
          [value]="day">{{ day }}</option>
      </select>
    </div>
  </div>
  <div class="form-row mt-3 mb-3">
    <div class="form-check form-check-inline" 
      *ngFor="let office of availableOffices">
      <input type="radio"
        name="office"
        id="office-{{ office.id }}"
        class="form-check-input"
        value="{{ office.name }}"
        [(ngModel)]="model.office">
      <label 
        for="office" 
        class="form-check-label">Ufficio {{ office.id }}</label>
    </div>
  </div>
  <div class="form-row mt-3 mb-3">
    <div class="form-check form-check-inline" 
      *ngFor="let application of applications; let i = index;">
      <input type="checkbox"
        name="application{{ application.id }}"
        id="application-{{ application.id }}"
        class="form-check-input"
        value="richiesta_{{ application.id }}"
        [(ngModel)]="model['application' + i]">
      <label 
        for="application" 
        class="form-check-label">Richiesta {{ application.id }}</label>
    </div>
  </div>
  <div class="form-row">
    <button 
      type="submit" 
      class="btn btn-primary">Prenota</button>
  </div>
</form>

<br>

<pre><code>{{ form.value | json }}</code></pre>

<br>

<pre><code>{{ model | json }}</code></pre>

Nel frammento di codice riportato sopra, oltre all’uso della direttiva *NgFor, abbiamo introdotto altre piccole, ma sostanziali modifiche rispetto alla versione precedente. Infatti, grazie alla direttiva ngModel abbiamo utilizzato il meccanismo del Two way data-binding per associare i valori dei diversi campi del form alle proprietà di un oggetto model del componente. In quest’ultimo abbiamo anche tre array che abbiamo utilizzato per inizializzare il form proprio attraverso la direttiva *NgFor.

import { Component, OnInit } from '@angular/core';

import { Appointment } from '../appointment';

@Component({
  selector: 'simple-template-driven-form',
  templateUrl: './template-driven-form.component.html',
  styleUrls: ['./template-driven-form.component.css']
})
export class TemplateDrivenFormComponent {
  daysOfTheWeek = [
    'Lunedì',
    'Martedì',
    'Mercoledì',
    'Giovedì',
    'Venerdì'
  ];

  availableOffices = [
    {id: 'A', name: 'ufficio_A'},
    {id: 'B', name: 'ufficio_B'},
    {id: 'C', name: 'ufficio_C'},
  ];

  applications = [
    {id: 0},
    {id: 1},
    {id: 2}
  ];

  model: Appointment = {
    name: '',
    mail: '',
    dayOfTheWeek: 'Lunedì',
    office: 'ufficio_A',
    application0: false,
    application1: false,
    application2: false
  };
}

La proprietà model rispecchia la struttura definita dall’interfaccia Appointment.

export interface Appointment {
  name: string;
  mail: string;
  dayOfTheWeek: string;
  office: string;
  application0: boolean;
  application1: boolean;
  application2: boolean;
}

Stato corrente del form e validazione

Sempre attraverso la direttiva NgModel Angular dà la possibilità di tener traccia dello stato corrente dei singoli campi aggiungendo a ciascuno di essi delle proprietà che possiamo controllare e utilizzare per mostrare dei messaggi di feedback all’utente o modificare altre sezioni del form o dell’applicazione.

Le proprietà dirty e pristine e le classi ng-dirty e ng-pristine

Le proprietà dirty e pristine permettono di capire se il campo di input a cui sono associate è stato modificato rispetto al valore iniziale, ovvero se l’utente ha modificato almeno una volta il suo valore. In tal caso dirty sarà pari a true e pristine sarà uguale a false. Le due proprietà sono infatti una l’opposto dell’altra e avranno valori invertiti fin quando l’utente non avrà ancora interagito con un certo elemento di tipo <input>. Quando una delle due proprietà è pari a true, Angular applica all’elemento una delle classi CSS ng-dirty o ng-pristine che possiamo sfruttare per variare l’aspetto del campo di input in modo da dare un feedback visivo all’utente sul suo stato corrente.

Le proprietà touched e untouched e le classi ng-touched e ng-untouched

La proprietà touched è pari a true quando si è verificato l’evento blur dell’elemento di input almeno una volta, ovvero quando l’utente, dopo aver interagito col campo, l’ha abbandonato. Se per esempio si clicca su un campo di input, generando l’evento focus, e poi si passa all’elemento successivo senza effettuare nessuna modifica, la proprietà touched diventa pari a true anche se, in questo caso particolare, dirty rimane uguale a false. Fin quando la proprietà touched è uguale a false, untouched assume il valore true. Come per le due proprietà viste in precedenza, Angular permette di modificare l’aspetto visivo di un elemento grazie alle due classi ng-touched e ng-untouched che vengono applicate nel momento in cui le rispettive proprietà assumono un valore uguale a true.

Le proprietà valid e invalid e le classi ng-valid e ng-invalid

Se stabiliamo dei criteri di validazione, possiamo sfuttare le due proprietà valid e invalid che, come è facile intuire, saranno pari a true quando il valore del campo di input rispetta (valid sarà true) o meno le regole di validazione imposte. In corrispondenza di tali proprietà, Angular attiva due classi CSS particolari che sono rispettivamente ng-valid, aggiunta quando la proprietà valid è pari a true, e ng-invalid.

Possiamo definire delle regole di validazione direttamente all’interno del template per ciascun elemento come mostrato nel frammento di codice sottostante per ‘Nome’ e ‘E-mail’.

<div class="col-md-4 mb-2">
  <label for="name">Nome</label>
  <input type="text"
    class="form-control"
    id="name"
    name="name"
    placeholder="Inserisci il tuo nome"
    [(ngModel)]="model.name"
    required
    minlength="2">
</div>
<div class="col-md-4 mb-2">
  <label for="mail">E-mail</label>
  <input type="email"
    class="form-control"
    id="mail"
    name="mail"
    placeholder="Inserisci la tua e-mail"
    [(ngModel)]="model.mail"
    required
    pattern="[a-z0-9._%+-]+@[a-z0-9-.]+.[a-z]{2,}$">
</div>

Nell’esempio riportato sopra abbiamo indicato che i due campi sono obbligatori (required). Inoltre ci si aspetta che venga inserito un nome di almeno due caratteri (minlength="2") e una mail che rispetti lo schema definito attraverso l’attributo pattern.

Riportiamo allora nel frammento di codice sottostante un possibile modo per ottenere le proprietà descritte finora per un certo campo del form.

<pre>
  <!-- Proprietà del campo di input -->
  <!-- identificato dall'attributo name="name" -->
  dirty? {{ form.form.controls.name.dirty }}
  pristine? {{ form.form.controls.name.pristine }}
  touched? {{ form.form.controls.name.touched }}
  untouched? {{ form.form.controls.name.untouched }}
  valid? {{ form.form.controls.name.valid }}
  invalid? {{ form.form.controls.name.invalid }}
</pre>

È possibile recuperare gli stessi dettagli accedendo direttamente alla proprietà controls resa disponibile da NgForm.

<pre>
  <!-- Proprietà del campo di input -->
  <!-- identificato dall'attributo name="mail" -->
  dirty? {{ form.controls.mail.dirty }}
  pristine? {{ form.controls.mail.pristine }}
  touched? {{ form.controls.mail.touched }}
  untouched? {{ form.controls.mail.untouched }}
  valid? {{ form.controls.mail.valid }}
  invalid? {{ form.controls.mail.invalid }}
</pre>

Possiamo però semplificare ulteriormente l’accesso alle proprietà di stato utilizzando una template reference variable come indicato nel frammento di codice riportato sotto.

<div class="col-md-4 mb-2">
  <label for="dayOfTheWeek">Giorno della settimana</label>
  <select
    name="dayOfTheWeek"
    id="dayOfTheWeek"
    class="form-control"
    [(ngModel)]="model.dayOfTheWeek"
    #dayOfTheWeek="ngModel">
    <option 
      *ngFor="let day of daysOfTheWeek" 
      [value]="day">{{ day }}</option>
  </select>
</div>

Sull’elemento di tipo <select> abbiamo assegnato alla variabile #dayOfTheWeek un riferimento ad un’istanza della direttiva ngModel. In questo modo possiamo accedere direttamente alle proprietà descritte in precedenza utilizzando la sintassi abbreviata riportata sotto.

<pre>
  <!-- Proprietà del campo di input -->
  <!-- identificato dall'attributo name="dayOfTheWeek" -->
  dirty? {{ dayOfTheWeek.dirty }}
  pristine? {{ dayOfTheWeek.pristine }}
  touched? {{ dayOfTheWeek.touched }}
  untouched? {{ dayOfTheWeek.untouched }}
  valid? {{ dayOfTheWeek.valid }}
  invalid? {{ dayOfTheWeek.invalid }}
</pre>

Messaggi di feedback per l’utente

È anche possibile servirsi delle proprietà analizzate per mostrare degli opportuni messaggi di feedback all’utente che sta compilando il modulo. A tale scopo può tornare utile utilizzare alcune direttive viste nelle precedenti lezioni come ngClass e *ngIf. Di seguito illustriamo un semplice esempio che fa vedere in che modo potremmo modificare il codice HTML relativo al campo ‘E-mail’ per segnalare eventuali errori.

<div class="col-md-4 mb-2">
  <label for="mail">E-mail</label>
  <input type="email"
    class="form-control"
    [ngClass]= "{
      'is-invalid': mail.invalid && mail.dirty,
      'is-valid': mail.valid && mail.dirty
    }"
    id="mail"
    name="mail"
    placeholder="Inserisci la tua e-mail"
    [(ngModel)]="model.mail"
    #mail="ngModel"
    required
    pattern="[a-z0-9._%+-]+@[a-z0-9-.]+.[a-z]{2,}$">
    <div
      *ngIf="mail.errors && mail.dirty"
      class="invalid-feedback">
      <p *ngIf="mail.errors.pattern" >
        Formato e-mail non valido
      </p>
      <p *ngIf="mail.errors.required" >
        * Campo obbligatorio
      </p>
    </div>
</div>

In questo caso abbiamo utilizzato la direttiva ngClass per aggiungere la classe CSS is-invalid quando non viene inserita una mail nel formato opportuno. Contemporaneamente viene anche mostrato un messaggio di errore che aiuta l’utente a completare il campo in maniera corretta.

Validazione dell’intero form

Così come per i singoli campi, possiamo accedere a delle simili proprietà per l’intero modulo attraverso la variabile (#form="ngForm") a cui abbiamo assegnato un’istanza della direttiva ngForm.

<div class="form-row">
  <button
    type="submit"
    class="btn "
    [ngClass]="{
      'btn-secondary': form.invalid,
      'btn-success': form.valid
    }"
    [disabled]="form.invalid">Prenota</button>
</div>

Nell’esempio riportato sopra abilitiamo il pulsante per l’invio del form solo se l’intero form è valido. In tal caso applichiamo anche la classe CSS btn-success.

Invio di un modulo

Per procedere all’invio del modulo basterà utilizzare un pulsante di tipo ‘submit’ all’interno del form e intercettare l’evento ngSubmit sull’elemento <form> al verificarsi del quale eseguiamo l’operazione che preferiamo.

<form novalidate #form="ngForm" (ngSubmit)="submitForm()">
  <!-- resto del codice -->
  <!-- ... -->
  <button 
    type="submit" 
    class="btn btn-success" 
    [disabled]="form.invalid">Prenota</button>
</form>

Nelle prossime lezioni vedremo come inviare i dati ad un server remoto utilizzando un servizio che insieme ai componenti, le direttive e le pipe costituiscono uno dei blocchi portanti di qualsiasi applicazione Angular.

Resettare un form compilato

È possibile resettare il modulo compilato attraverso il metodo reset() che possiamo invocare essenzialmente in due modi. Il primo, e più semplice, consiste nel resettare il form direttamente dal template. In questo caso possiamo accedere all’elemento <form> attraverso la variabile #form come mostrato nel frammento di codice riportato sotto.

<button
type="submit"
class="btn btn-danger"
(click)="form.reset()"
[disabled]="form.invalid">Reset</button>

Se vogliamo però resettare il form all’interno di un qualsiasi metodo del componente, abbiamo due possibilità.

La prima consiste nel passare un riferimento alla direttiva ngForm come argomento di un metodo attraverso una Template reference variable.

<form novalidate #form="ngForm" (ngSubmit)="submitForm(form)">
  <!-- resto del codice -->
  <!-- ... -->
  <button 
    type="submit" 
    class="btn btn-success" 
    [disabled]="form.invalid">Prenota</button>
</form>
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';

import { Appointment } from '../appointment';

@Component({
  selector: 'simple-template-driven-form',
  templateUrl: './template-driven-form.component.html',
  styleUrls: ['./template-driven-form.component.css']
})
export class TemplateDrivenFormComponent {

  // ...

  submitForm(form: NgForm) {
    form.reset();
    console.log('Form submission');
  }
}

Il secondo metodo consiste nell’ottenere un riferimento al form attraverso il decoratore @ViewChild() a cui passiamo come argomento una stringa che coincide con il nome della Template reference variable presente nel template.

<form novalidate #form="ngForm" (ngSubmit)="submitForm()">
  <!-- resto del codice -->
  <!-- ... -->
  <button 
    type="submit" 
    class="btn btn-success" 
    [disabled]="form.invalid">Prenota</button>
</form>
import { Component, OnInit, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';

import { Appointment } from '../appointment';

@Component({
  selector: 'simple-template-driven-form',
  templateUrl: './template-driven-form.component.html',
  styleUrls: ['./template-driven-form.component.css']
})
export class TemplateDrivenFormComponent {

  @ViewChild('form') form: NgForm;

  // ...

  submitForm() {
    this.form.reset();
    console.log('Form submission');
  }
}

Riepilogo

In questa lezione abbiamo illustrato come poter usare l’approccio template-driven per creare dei moduli e sfruttare le potenzialità di Angular che consentono di visualizzare lo stato di un singolo campo, validare il suo contenuto, mostrare degli opportuni messaggi di feedback all’utente e inviare il form. Abbiamo però testato con mano che, aggiungendo nuove funzionalità, il template di un componente diventa piuttosto affollato e il codice risulta difficile da leggere. Anche per questo motivo Angular dà la possibilità di creare dei form utilizzando un approccio alternativo che consente di spostare la logica di controllo e validazione del form all’interno della definizione del componente. Nella prossima lezione discuteremo quindi dei Reactive forms (o Model-driven forms).

Pubblicitร