Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [Angular] Bloccare pagina se il form non è salvato

    ciao!

    avrei la necessità di bloccare la pagina se il form non è stato salvato.
    più precisamente dovrò far comparire la classica finestra modale con la richiesta di conferma di uscita dalla pagina.

    io ho creato una piccola funzione che mi controlla i valori del form originale e quello modificato:
    codice:
      checkItems(): void {
        // console.log(this.originalItem, this.newItem);
        if (!_.isEqual(this.originalItem, this.newItem)) {
          alert('KO');
        }
      }
    per ora l'ho richiamata solo sul click di un bottone, e funziona.
    quello che non ho capito è come collegarla a tutti i link, o in generale ad una qualsiasi cosa che mi sta facendo uscire dalla pagina.
    quindi anche ad un eventuale refresh.

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Credo tu debba intercettare l'evento OnUnload, ma se cerchi in giro troverai senz'altro tonnellate di esempi (non mi pare una problematica nuova).
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Quote Originariamente inviata da alka Visualizza il messaggio
    Credo tu debba intercettare l'evento OnUnload, ma se cerchi in giro troverai senz'altro tonnellate di esempi (non mi pare una problematica nuova).
    ciao alka!

    no figurati, non è assolutamente una problematica nuova.
    solo che per angular ho trovato solo esempi sul beforeunload tipo questo:
    codice:
        window.addEventListener("beforeunload", (event) => {
          event.preventDefault();
          event.returnValue = "Unsaved modifications";
          return event;
        });
    che non viene intercettato dai link, ma solo dal refresh.

    cmq ho fatto una breve ricerca, e a questo link vedo che è sconsigliato usare unload: https://developer.mozilla.org/en-US/...w/unload_event
    faccio cmq una prova e vediamo che esce fuori!

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Quote Originariamente inviata da fermat Visualizza il messaggio
    non viene intercettato dai link, ma solo dal refresh.
    Questo è ovvio, in quanto il link di fatto non ricarica la pagina, ma segnala ad Angular la necessità di creare una nuova vista.
    In quel frangente, devi intercettare il cambio di indirizzo tramite il sistema di Routing, a seconda di come hai strutturato l'applicazione.

    Quote Originariamente inviata da fermat Visualizza il messaggio
    a questo link vedo che è sconsigliato usare unload
    Sì, però nelle note ti dice anche perché (su device mobile non si scatena l'evento se l'utente passa ad altra app e poi chiude forzatamente il browser). Se puoi ignorare queste casistiche, l'evento si può adoperare tranquillamente, anche se l'esperienza cambia da desktop a mobile.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Quote Originariamente inviata da alka Visualizza il messaggio
    Questo è ovvio, in quanto il link di fatto non ricarica la pagina, ma segnala ad Angular la necessità di creare una nuova vista.
    In quel frangente, devi intercettare il cambio di indirizzo tramite il sistema di Routing, a seconda di come hai strutturato l'applicazione.


    Sì, però nelle note ti dice anche perché (su device mobile non si scatena l'evento se l'utente passa ad altra app e poi chiude forzatamente il browser). Se puoi ignorare queste casistiche, l'evento si può adoperare tranquillamente, anche se l'esperienza cambia da desktop a mobile.

    Ciao!
    uhm no, direi che non posso evitare queste casistitche nel 2023 .

    faccio una ricerca sul cambio di rotta!

  6. #6
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,301
    Quote Originariamente inviata da fermat Visualizza il messaggio
    uhm no, direi che non posso evitare queste casistitche nel 2023 .
    Il problema è proprio che queste casistiche - volente o nolente - si verificano a prescindere, e non hai alcuna possibilità di controllo su di esse, in quanto è il sistema operativo a gestirle.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  7. #7
    per ottenere questa cosa in angular ho usato una GUARD:
    codice:
    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;
      }
    
    }
    l'interfaccia server per poter passare il componente attuale senza cablarlo direttamente nella guard:
    codice:
    ........
    
    @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;
      }
    
    }
    nel module dovete attivare la guarda; ad esempio:
    codice:
    .............
    
    @NgModule({
      providers: [
        FormGuard
      ],
      declarations: [
        MostraComponent,
      ],
      imports: [
        CommonModule,
        RouterModule.forChild([
          {
            path: 'mostra',
            component: MostraComponent,
            data: {title: 'Mostra'},
            canDeactivate: [FormGuard],
          },
        ]),
        .............
      ]
    })
    
    export class MostreModule {
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.