Avvisare l'utente delle modifiche non salvate in un Angular form

Mattepuffo's logo
Avvisare l'utente delle modifiche non salvate in un Angular form

Avvisare l'utente delle modifiche non salvate in un Angular form

In sostanza vogliamo avvisare l'utente se ha modificato un form e poi non lo ha salvato, ma sta uscendo dalla pagina.

Tutto questo in Angular.

Per ottenere questo risultato possiamo usare le guard; quindi come prima cosa creiamoci la nostra che implementerà CanDeactivate:

import {Injectable} from '@angular/core';
import {CanDeactivate} from '@angular/router';
import {Observable} from "rxjs";

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean | Observable<boolean>;
}

@Injectable()
export class FormGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
    if (!component.canDeactivate()) {
      return confirm('I dati non sono stati salvati, sei sicuro di voler uscire?');
    }
    return true;
  }

}

Quell'interfaccia ci servirà per essere usata in tutti i componenti dove vogliamo effettuare il controllo; se ne abbiamo solo uno, possiamo richiamare direttamente il componente.

A questo punto vediamo un componente:

........

@Component({
  selector: 'app-mostra',
  templateUrl: './mostra.component.html',
  styleUrls: ['./mostra.component.scss'],
})

export class MostraComponent implements OnInit, ComponentCanDeactivate {

  frm: FormGroup;
  
  constructor(
     ........
  ) {}

  ngOnInit(): void {
    ...............

    this.initForm();
  }

  initForm(): void {
    this.frm = new FormGroup({
      id: new FormControl(this.item.id),
      titolo: new FormControl(this.item.titolo, Validators.required),
      sede: new FormControl(this.item.sede, Validators.required),
      data_inizio: new FormControl(this.item.data_inizio, Validators.required),
      data_fine: new FormControl(this.item.data_fine, Validators.required),
      note: new FormControl(this.item.note),
    });
  }

  ...........

  canDeactivate(): boolean | Observable<boolean> {
    return !this.frm.dirty;
  }

}

Vi ho messo solo le parti interessate; come vedete dobbiamo implementare l'intrefaccia creata nella guard, con la funzione che in pratica controlla il form.

Infine nel modulo di riferimento del componente:

.............

@NgModule({
  providers: [
    FormGuard
  ],
  declarations: [
    MostraComponent,
  ],
  imports: [
    CommonModule,
    RouterModule.forChild([
      {
        path: 'mostra',
        component: MostraComponent,
        data: {title: 'Mostra'},
        canDeactivate: [FormGuard],
      },
    ]),
    .............
  ]
})

export class MostreModule {
}

Enjoy!


Condividi

Commentami!