Saltar al contenido

Diálogo modal de uso angular en el servicio canDeactivate Guard para cambios no enviados (formulario sucio)

Si encuentras algo que no comprendes nos puedes dejar un comentario y te responderemos lo más rápido posible.

Solución:

Lo resolví usando ngx-bootstrap Modals y RxJs Subjects.

En primer lugar, creé un componente modal:

import  Component  from '@angular/core';
import  Subject  from 'rxjs/Subject';
import  BsModalRef  from 'ngx-bootstrap';

@Component(
  selector: 'app-confirm-leave',
  templateUrl: './confirm-leave.component.html',
  styleUrls: ['./confirm-leave.component.scss']
)
export class ConfirmLeaveComponent 

  subject: Subject;

  constructor(public bsModalRef: BsModalRef)  

  action(value: boolean) 
    this.bsModalRef.hide();
    this.subject.next(value);
    this.subject.complete();
  

aquí está la plantilla:




Luego modifiqué mi guardia usando un Asunto, ahora se ve así:

import  CanDeactivate  from '@angular/router';
import  FormGroup  from '@angular/forms';
import  Injectable  from '@angular/core';
import  Subject  from 'rxjs/Subject';
import  BsModalService  from 'ngx-bootstrap';

import  ConfirmLeaveComponent  from '.....';

export interface FormComponent 
  form: FormGroup;


@Injectable()
export class UnsavedChangesGuardService implements CanDeactivate 

  constructor(private modalService: BsModalService) 

  canDeactivate(component: FormComponent) 
    if (component.form.dirty) 
      const subject = new Subject();

      const modal = this.modalService.show(ConfirmLeaveComponent, 'class': 'modal-dialog-primary');
      modal.content.subject = subject;

      return subject.asObservable();
    

    return true;
  

En el archivo app.module.ts, vaya a la sección @NgModule y agregue el componente ConfirmLeaveComponent a entryComponents.

@NgModule(
  entryComponents: [
    ConfirmLeaveComponent,
  ]
)

Además de la buena solución de ShinDarth, vale la pena mencionar que también tendrá que cubrir un rechazo del modal, porque es posible que el método action () no se active (por ejemplo, si permite el botón esc o hace clic fuera del modal) . En ese caso, el observable nunca se completa y su aplicación podría atascarse si la usa para enrutamiento.

Lo logré suscribiéndome al bsModalService onHide propiedad y fusionando esto y el sujeto de acción juntos:

confirmModal(text?: string): Observable 
    const subject = new Subject();
    const modal = this.modalService.show(ConfirmLeaveModalComponent);
    modal.content.subject = subject;
    modal.content.text = text ? text : 'Are you sure?';
    const onHideObservable = this.modalService.onHide.map(() => false);
    return merge(
      subject.asObservable(),
      onHideObservable
    );
  

En mi caso mapeo lo mencionado onHide observable a false porque un despido se considera un aborto en mi caso (solo un clic en ‘sí’ producirá un resultado positivo para mi modal de confirmación).

Simplemente expandiendo la información adicional proporcionada por mitschmidt con respecto a hacer clic fuera / botón de escape, este método canDeactivate funciona con el código de Francesco Borzi. Solo agrego la suscripción a onHide () en línea en la función:

canDeactivate(component: FormComponent) 
        if (component.form.dirty) 
            const subject = new Subject();

            const modal = this.modalService.show(ConfirmLeaveComponent,  'class': 'modal-dialog-primary' );
            modal.content.subject = subject;

            this.modalService.onHide.subscribe(hide => 
                subject.next(false);
                return subject.asObservable();
            );

            return subject.asObservable();
        

        return true;
    

Te mostramos las reseñas y valoraciones de los lectores

Acuérdate de que tienes autorización de aclarar tu experiencia .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *