Nous enveloppons dans une fenêtre de confirmation modale Promise

Lorsque l'utilisateur effectue des actions critiques et / ou irréversibles, avant d'envoyer une demande au serveur, vous devez en demander la confirmation à l'utilisateur.

En règle générale, le modal «Êtes-vous sûr de vouloir faire ceci et cela et cela» s'affiche et il y a deux boutons ci-dessous: Oui et Non. Si l'utilisateur clique sur «oui», nous envoyons une demande au serveur et fermons le modal. Sinon, fermez simplement le modal.

Il s'agit d'une fonctionnalité standard couramment utilisée à plusieurs endroits d'un projet. De plus, lors de la création des fonctionnalités du projet, il est probable que vous ajoutiez quelques endroits supplémentaires où des modaux avec confirmation sont nécessaires. Par conséquent, afin d'éviter la duplication de code, un tel modal doit sans ambiguïté être retiré dans un composant distinct. Pour éviter la tentation de marteler des béquilles, ce composant doit être aussi polyvalent et facile à utiliser que possible.

Passons des paroles à l'action. Pour afficher le modal, nous utiliserons Bootstrap.

En fait ma version d'un tel composant:

oui-non-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 -->

oui-non-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 {}

}

J'ai mis le titre de l'avertissement, le texte de l'avertissement, le schéma de couleurs / le niveau de gravité (danger, info, avertissement) dans les paramètres, vous pouvez également redéfinir l'étiquette sur les boutons.

Pour afficher le modal, appelez showAsync, dans lequel nous pouvons transférer des données arbitraires. Nous obtenons les mêmes données en résolution / rejet.

Ensuite, connectez le modal dans un autre composant:

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 {
  }
}

À mon avis, l'utilisation d'une telle solution semble aussi simple et lisible que possible.

À titre de comparaison, lorsque vous utilisez EventEmitter, vous devrez définir deux méthodes dans chaque composant - showDeleteModal (), qui est appelée en cliquant sur le bouton Supprimer, et la méthode delete (), qui est appelée par l'événement modal. Si vous avez plusieurs de ces modaux dans un composant pour différentes actions de l'utilisateur, la lisibilité du code en souffrira déjà.

Dans les commentaires, comme toujours, j'attends des critiques constructives et raisonnables.

All Articles