Envolvemos en una ventana de confirmación modal Promesa

Cuando el usuario realiza algunas acciones críticas y / o irreversibles, antes de enviar una solicitud al servidor, debe pedirle confirmación al usuario.

Como regla general, se muestra el modo "¿Está seguro de que desea hacer esto y aquello y aquello?" Y hay dos botones a continuación: Sí y No. Si el usuario hizo clic en "sí", enviamos una solicitud al servidor y cerramos el modal. Si no, simplemente cierre el modal.

Esta es una funcionalidad estándar que se usa comúnmente en varios lugares de un proyecto. Además, al construir la funcionalidad del proyecto, es probable que agregue algunos lugares más donde se necesitan modales con confirmación. Por lo tanto, para evitar la duplicación de código, sin ambigüedad, dicho modal debe eliminarse en un componente separado. Para evitar la tentación de martillar muletas, este componente debe ser lo más versátil y fácil de usar posible.

Pasemos de la letra a la acción. Para mostrar el modal, usaremos Bootstrap.

En realidad, mi versión de dicho componente:

yes-no-modal.component.html
<div bsModal #yesNoModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-{{type}}" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title">{{title}}</h4>
        <button type="button" class="close" (click)="onNoClick()" aria-label="Close">
          <span aria-hidden="true">×</span>
        </button>
      </div>
      <div class="modal-body">
        <p>{{body}}</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" (click)="onNoClick()">{{noBtnText}}</button>
        <button type="button" class="btn btn-{{type}}" (click)="onYesClick()">{{yesBtnText}}</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

yes-no-modal.component.ts
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {ModalDirective} from 'ngx-bootstrap/modal';

@Component({
  selector: 'app-yes-no-modal',
  templateUrl: './yes-no-modal.component.html',
  styleUrls: ['./yes-no-modal.component.css']
})
export class YesNoModalComponent implements OnInit {

  @ViewChild('yesNoModal') public yesNoModal: ModalDirective;

  @Input() private type = 'info';
  @Input() private title = '';
  @Input() private body = '';
  @Input() private yesBtnText = '';
  @Input() private noBtnText = '';

  constructor() { }

  ngOnInit(): void {
  }

  public showAsync(data = null): Promise<any> {
    return new Promise<any>((resolve, reject) => {
      this.yesNoModal.show();
      this.onYesClick = () => {
        this.yesNoModal.hide();
        resolve(data);
      };
      this.onNoClick = () => {
        this.yesNoModal.hide();
        reject(data);
      };
    });
  }

  private onYesClick(): any {}
  private onNoClick(): any {}

}

Pongo el título de advertencia, el texto de advertencia, el esquema de color / nivel de gravedad (peligro, información, advertencia) en los parámetros, también puede redefinir la etiqueta en los botones.

Para mostrar el modal, llame a showAsync, en el que podemos transferir datos arbitrarios. Obtenemos los mismos datos en resolución / rechazo.

Luego, conecte el modal en otro componente:

account.component.html
<app-yes-no-modal
  #deleteModal
  body="     ?"
  title=""
  type="danger"
></app-yes-no-modal>
<button (click)="delete()"></button>

account.component.ts
import {Component, OnInit, ViewChild} from '@angular/core';
import {YesNoModalComponent} from '../_common/yes-no-modal/yes-no-modal.component';
import {DeleteUserEndpoint} from '../../api/delete-user.endpoint';
import {ErrorService} from '../../services/error/error.service';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html',
  styleUrls: ['./account.component.css'],
  providers: [DeleteUserEndpoint]
})
export class AccountComponent implements OnInit {


  @ViewChild('deleteModal') public deleteModal: YesNoModalComponent;

  constructor (private deleteUserEndpoint: DeleteUserEndpoint) {
  }

  delete(data) {
    this.deleteModal.showAsync(data).then(result => {
      this.deleteUserEndpoint.execute(result);
    });
  }

  ngOnInit(): void {
  }
}

En mi opinión, el uso de tal solución parece lo más simple y legible posible.

A modo de comparación, cuando use EventEmitter, tendrá que definir dos métodos en cada componente: showDeleteModal (), que se llama haciendo clic en el botón Eliminar, y el método delete (), que se llama mediante el evento modal. Si tiene varios modales de este tipo en un componente para diferentes acciones del usuario, la legibilidad del código ya se verá afectada.

En los comentarios, como siempre, espero críticas constructivas y razonables.

All Articles