3

J'utilise Bootstrap conjointement avec AngularJS pour ouvrir les boîtes de dialogue modales. Pour activer un modal sans écrire de code JavaScript, j'utilise les attributs de données comme décrit dans le documentation. C'est un moyen très pratique, car je n'ai pas besoin d'afficher/masquer la boîte de dialogue manuellement.Attribut de données à appeler lorsque le dialogue modal est fermé

<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button> 

Maintenant, je voudrais appeler une méthode lorsque la boîte de dialogue modale est fermée. Avec un bouton de fermeture explicite, ce n'est pas un problème. Cependant, lorsque l'utilisateur clique en dehors de la boîte de dialogue ou appuie sur la touche Esc, je ne peux déclencher aucune fonction explicitement.

Je sais que je peux utiliser jQuery ou $uibModal d'Angular pour écouter un événement de rejet, mais cela complique l'ensemble du projet. Je préférerais tout avoir au même endroit. Je ne veux pas mélanger les choses, donc utiliser jQuery dans mon projet AngularJS n'est pas une option. La solution avec laquelle je suis coincé est d'utiliser $uibModal à open() la boîte de dialogue manuellement et d'attraper le résultat pour gérer le rejet invoqué par l'utilisateur.

Ma question:

Comment puis-je appeler une fonction quand une boîte de dialogue modale est fermée sans introduire trop de désordre?

Ce que j'ai à l'esprit ressemble à ceci (imaginaire data-dismiss-callback):

<button type="button" data-toggle="modal" 
         data-target="#myModal" 
         data-dismiss-callback="handleCloseEvent()">Launch modal</button> 
+0

Semble enveloppez dialogue modale bootstrap dans un composant personnalisé (directive) puis manipulons l'événement de rejet est une option. –

Répondre

1

Comme nous voulons associer un comportement spécifique (rappel personnalisé) à la modal cible à l'aide du bouton qui ouvre, puis directive est le meilleur candidat qui peut nous aider à atteindre cet objectif. Nous écouterons show.bs.modal and hide.bs.modal/hidden.bs.modal events: le premier nous aidera à déterminer si le modal a été ouvert en utilisant le bouton correspondant et le second est l'endroit où nous voulons appeler la fonction de rappel passé.

Voici un exemple concret de modalDismissCallback directive (due to normalization, nous ne pouvons pas nommons dataDismissCallback):

angular.module('myDemoApp', []) 
 
    .controller('myCtrl', [function() { 
 
     var ctrl = this; 
 
     ctrl.testVar = 2; 
 
     ctrl.onModalDismiss = onModalDismiss; 
 

 
     function onModalDismiss(a, e) { 
 
      console.log(arguments); 
 
     } 
 

 
     return ctrl; 
 
    }]) 
 
    .directive('modalDismissCallback', [function modalDismissCallback() { 
 
     return { 
 
      restrict: 'A', 
 
      scope: { 
 
       modalDismissCallback: '&' 
 
      }, 
 
      link: function (scope, element) { 
 
       var modal = angular.element(element.data('target')); 
 

 
       modal.on('show.bs.modal', onShow); 
 
       modal.on('hide.bs.modal', onHide); 
 

 
       scope.$on('$destroy', function() { 
 
        modal.off('show.bs.modal', onShow); 
 
        modal.off('hide.bs.modal', onHide); 
 
       }); 
 
       
 
       var shouldCall = false; 
 

 
       function onShow(e) { 
 
        shouldCall = e.relatedTarget === element[0]; 
 
       } 
 

 
       function onHide(e) { 
 
        if (angular.isFunction(scope.modalDismissCallback) && shouldCall) { 
 
         scope.$event = e; 
 
         scope.$applyAsync(function() { 
 
          scope.modalDismissCallback.apply(this, arguments); 
 
         }); 
 
        } 
 
       } 
 
      } 
 
     } 
 
    }]);
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.min.css"> 
 

 
<body ng-app="myDemoApp"> 
 

 
<div ng-controller="myCtrl as $ctrl"> 
 

 
    <button type="button" class="btn btn-default" 
 
      data-toggle="modal" 
 
      data-target="#myModal" 
 
      modal-dismiss-callback="$ctrl.onModalDismiss($ctrl.testVar, $event)">Launch modal 
 
    </button> 
 
    
 
    <button type="button" class="btn btn-default" 
 
      data-toggle="modal" 
 
      data-target="#myModal">Launch modal wo callback 
 
    </button> 
 

 
    <div id="myModal" class="modal fade bd-example-modal-sm" tabindex="-1" role="dialog" 
 
     aria-labelledby="mySmallModalLabel" aria-hidden="true"> 
 

 

 
     <div class="modal-dialog" role="document"> 
 
      <div class="modal-content"> 
 
       <div class="modal-header"> 
 
        <h4 class="modal-title" id="myModalLabel">Modal title</h4> 
 
       </div> 
 
       <div class="modal-body"> 
 
        <div ng-include="'template.html'"></div> 
 
       </div> 
 
       <div class="modal-footer"> 
 
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
 
       </div> 
 
      </div> 
 
     </div> 
 

 
    </div> 
 
</div> 
 

 
<script type="text/ng-template" id="template.html"><h5>Hello from ng-template!</h5></script> 
 
</body> 
 

 

 

 

 
<script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.slim.js"></script> 
 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script> 
 
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/js/bootstrap.min.js"></script>