web-dev-qa-db-fra.com

Comment gérer de manière générale le rejet éventuellement non géré: clic en arrière-plan

J'ai un service angular pour gérer les modaux:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    return $uibModal.open(options);
  }
});

Maintenant, je suis passé à angular 1.6 et j'ai eu cette erreur:

Rejet éventuellement non géré: clic en arrière-plan

chaque fois que j'ouvre un modal et clique ailleurs (en toile de fond) et le modal se ferme (comme prévu). Je veux donc gérer ce unhandled exception dans mon ModalService car je ne veux pas gérer ce cas chaque fois que j'utilise le ModalService. Il est toujours correct de fermer le modal via un clic de fond, cela ne fait pas exception.

J'ai essayé:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    var modalInstance = $uibModal.open(options);
    modalInstance.result.catch(function error(error) {
      if(error === "backdrop click") {
        // do nothing
      } else {
        throw error;
      }
    })
    return modalInstance;
  }
});

Mais cela conduit au problème que je ne peux pas gérer d'autres erreurs que backdrop click comme ils sont toujours jetés:

ModalService.open({...}).result.catch(function(error) {
  // this will catch the error too, but the throw in the ModalService
  // will occure in parallel and will not be catched by this function
});

Et si je l'essaye comme ça:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    var modalInstance = $uibModal.open(options);
    modalInstance.result.then(function(whatever) {
      return whatever;
    }, function rejection(error) {
      return error;
    });
    return modalInstance;
  });
});

il résout l'erreur de "rejet non géré", mais pour chaque cas, pas seulement pour "backdrop clicked".

Quelqu'un at-il une bonne solution pour ce cas?

21
Andi

Malheureusement, c'est ainsi qu'ils le gèrent dans Le Plucker officiel pour Modal (ui.bootstrap.modal) .

Si vous cliquez sur un bouton, il enregistre quelque chose comme ceci:

Modal licencié le: jeu.23 février 2017 21:54:26 GMT-0300 (Pacifique SA heure d'été)

Ce qu'ils font c'est:

modalInstance.result.then(function (selectedItem) {
  $ctrl.selected = selectedItem;
}, function () {
  $log.info('Modal dismissed at: ' + new Date());
});

Si vous supprimez le rappel d'erreur, devinez ce que vous obtenez:

Rejet éventuellement non géré: clic en arrière-plan

Et même sur annuler

Rejet éventuellement non géré: annuler

Jusqu'à présent, vous faites cela ou utilisez cette solution de contournement pour réduire au silence les rejets non gérés

app.config(['$qProvider', function ($qProvider) {
            $qProvider.errorOnUnhandledRejections(false);
        }]);
21
Veglos

utilisez ceci

 $uibModal.open({
                    ////your code......
}).result.then(function(){}, function(res){})

maintenant ça ne vous donnera pas d'erreur

9

Dépend des spécifications de l'interface utilisateur.

Ce n'est PAS la meilleure solution de contournement s'il existe des spécifications d'interface utilisateur que l'utilisateur final doit être en mesure de cliquer EN DEHORS du modal pour fermer le modal.

Si ce n'est PAS le cas et qu'il y a un petit "x" en haut à droite du modal et/ou il y a une fermeture

toile de fond: faux, // <<< !!!!!!! (voir code ci-dessous)
empêchera l'utilisateur final de cliquer EN DEHORS du modal pour fermer le modal.

$scope.change = function (changeableData, p_Mode) {
    var modalInstance = $uibModal.open({
        templateUrl: whatever,
        controller: ModalInstanceCtrl,
        scope: $scope,
        backdrop: false,  // <<< !!!!!!!
        resolve: {
            // whatever
        }
    });  

Cela empêchera l'erreur "Rejet éventuellement non géré: clic en arrière-plan" de se produire.

Encore une fois, vous devez consulter les spécifications de l'interface utilisateur et/ou obtenir la permission des analystes pour l'implémenter.

4
gBerger101

Si vous utilisez un contrôleur dans votre modal. Je l'ai utilisé lors de l'événement de clôture. Parce que "Clôture" est valide mais "Rejeter" est un rejet. Cela va dans votre contrôleur modal, pas dans le parent.

            $scope.$on('modal.closing', (event, reason, closed) => {
                if (!closed) {
                    event.preventDefault();
                    $scope.$close("Closing");   
                }

            });

Ainsi, votre clic en arrière-plan déclenchera l'événement de clôture mais fermé sera transmis faux. Si tel est le cas, évitez le comportement par défaut et fermez le modal par programme au lieu de le supprimer. Gardez à l'esprit que cela rompra l'utilisation du rejet, si vous souhaitez l'utiliser à sa fin d'origine.

3
Malcor