web-dev-qa-db-fra.com

Affichage de l'alerte dans angularjs lorsque l'utilisateur quitte une page

Je suis une nouvelle abeille angularjs. J'essaie d'écrire une validation qui alerte l'utilisateur lorsqu'il essaie de fermer la fenêtre du navigateur.

J'ai 2 liens sur ma page v1 et v2.When cliqué sur les liens qu'il prend pour les pages spécifiques. Voici le code pour rediriger vers v1 et v2

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives'])

.config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/v1', {templateUrl: 'pages/v_1.html', controller: MyCtrl1});
        $routeProvider.when('/v2', {templateUrl: 'pages/v_2.html', controller: MyCtrl2});
        $routeProvider.otherwise({redirectTo: '/v1'});
}]);

Je souhaite faire apparaître un message lorsque l'utilisateur clique sur v1 qu'il est sur le point de "quitter la v1 s'il souhaite continuer" et de même en cliquant sur v2. Toute indication sur la façon de réaliser cela serait appréciée.

J'ai eu une réponse ici mais le message s'affiche après chaque intervalle de temps.

Code mis à jour;

Contrôleurs

function MyCtrl1() {
    $scope.$on('$locationChangeStart', function (event, next, current) {
        if ('your condition') {
            event.preventDefault();

            MessageService.showConfirmation(
                'Are you sure?',
            MessageService.MessageOptions.YES_NO, {
                'YES': function () {
                    blockNavigation = false;
                    $location.url($location.url(next).hash());
                    $rootScope.$apply();
                },
                'NO': function () {
                    MessageService.clear();
                    $log.log('NO Selected')
                }
            });
        }
    });
}
MyCtrl1.$inject = [];


function MyCtrl2() {}
MyCtrl2.$inject = [];
58
iJade

Le code pour le dialogue de confirmation peut être écrit plus court de cette façon:

$scope.$on('$locationChangeStart', function( event ) {
    var answer = confirm("Are you sure you want to leave this page?")
    if (!answer) {
        event.preventDefault();
    }
});
105
Scheintod

Permet de séparer votre question, vous posez des questions sur deux choses différentes:

1.

J'essaie d'écrire une validation qui alerte l'utilisateur lorsqu'il essaie de fermer la fenêtre du navigateur.

2.

Je souhaite faire apparaître un message lorsque l'utilisateur clique sur v1 qu'il est sur le point de "quitter la v1 s'il souhaite continuer" et de même en cliquant sur v2.

Pour la première question, procédez comme suit:

window.onbeforeunload = function (event) {
  var message = 'Sure you want to leave?';
  if (typeof event == 'undefined') {
    event = window.event;
  }
  if (event) {
    event.returnValue = message;
  }
  return message;
}

Et pour la deuxième question, procédez comme suit:

Vous devriez gérer le $locationChangeStart event afin de se connecter pour voir l’événement de transition, utilisez donc ce code pour gérer la validation de la transition dans votre/vos contrôleur (s):

function MyCtrl1($scope) {
    $scope.$on('$locationChangeStart', function(event) {
        var answer = confirm("Are you sure you want to leave this page?")
        if (!answer) {
            event.preventDefault();
        }
    });
}
43
Yair Nevet

Voici la directive que j'utilise. Il se nettoie automatiquement lorsque le formulaire est déchargé. Si vous souhaitez empêcher l'invite de se déclencher (par exemple, parce que vous avez correctement enregistré le formulaire), appelez $ scope.FORMNAME. $ SetPristine (), où FORMNAME est le nom du formulaire que vous souhaitez empêcher de l'invite.

.directive('dirtyTracking', [function () {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attrs) {
            function isDirty() {
                var formObj = $scope[$element.attr('name')];
                return formObj && formObj.$pristine === false;
            }

            function areYouSurePrompt() {
                if (isDirty()) {
                    return 'You have unsaved changes. Are you sure you want to leave this page?';
                }
            }

            window.addEventListener('beforeunload', areYouSurePrompt);

            $element.bind("$destroy", function () {
                window.removeEventListener('beforeunload', areYouSurePrompt);
            });

            $scope.$on('$locationChangeStart', function (event) {
                var Prompt = areYouSurePrompt();
                if (!event.defaultPrevented && Prompt && !confirm(Prompt)) {
                    event.preventDefault();
                }
            });
        }
    };
}]);
22

Comme vous l'avez découvert ci-dessus, vous pouvez utiliser une combinaison de window.onbeforeunload et $locationChangeStart pour envoyer un message à l'utilisateur. De plus, vous pouvez utiliser ngForm.$dirty pour ne signaler à l'utilisateur que les modifications apportées.

J'ai écrit une directive angularjs que vous pouvez appliquer à tout formulaire qui surveillera automatiquement les modifications et avertira l'utilisateur s'il recharge la page ou s'il quitte la page. @see https://github.com/facultymatt/angular-unsavedChanges

J'espère que vous trouverez cette directive utile!

9
facultymatt

Les autres exemples ici fonctionnent bien pour les anciennes versions de ui-router (> = 0.3.x) mais tous les événements d’état, tels que $stateChangeStart, are déconseillé à partir de 1. . Le nouveau code ui-router 1.0 utilise le $ transitions service . Donc, vous devez injecter $transitions dans votre composant, utilisez ensuite la méthode $ transitions.onBefore comme le montre le code ci-dessous.

 $ transitions.onBefore ({}, fonction (transition) {
 renvoyer confirmer ("Êtes-vous sûr de vouloir quitter cette page?"); 
}); ____.]

Ceci est juste un exemple super simple. Le $transitions service peut accepter des réponses plus complexes telles que des promesses. Voir le type HookResult pour plus d'informations.

2
Brent Matzelle