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 quand il essaie de fermer la fenêtre du navigateur.

j'ai 2 liens sur ma page v1 et v2.Lorsque vous cliquez sur les liens, vous accédez aux 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 veux afficher un message lorsque l'utilisateur clique sur v1 qu'il est sur le point de quitter à partir de v1, s'il veut continuer" et même en cliquant sur v2. Tout conseils sur la façon d'y parvenir serait appréciée.

j'ai obtenu une réponse ici , mais il apparaît le message 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 = [];
56
demandé sur Community 2013-02-11 13:55:14

6 réponses

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();
    }
});
103
répondu Scheintod 2013-08-21 11:04:06

permet de séparer votre question, vous posez deux questions différentes:

1.

j'essaie d'écrire une validation qui alerte l'utilisateur quand il essaie pour fermer la fenêtre du navigateur.

2.

je veux faire apparaître un message quand l'utilisateur clique sur v1 qu'il est sur partir de v1, s'il souhaite continuer" et même en cliquant sur v2.

pour la première question, faites-le de cette façon:

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, faites - le de cette façon:

vous devez gérer l'événement $locationChangeStart afin de vous connecter pour voir l'événement de transition, utilisez donc ce code pour gérer la validation de transition dans votre controller/ 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();
        }
    });
}
42
répondu Yair Nevet 2016-02-09 09:35:43

Voici la directive que j'utilise. Il se nettoie automatiquement lorsque le formulaire est déchargé. Si vous voulez empêcher l'invite de s'allumer (par exemple parce que vous avez réussi à sauvegarder le formulaire), appelez $scope.FORMNAME.$setPristine (), où FORMNAME est le nom du formulaire que vous voulez empêcher de lancer.

.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
répondu Christopher Davies 2014-04-04 15:11:22

Comme vous l'avez découvert ci-dessus, vous pouvez utiliser une combinaison de window.onbeforeunload et $locationChangeStart message à l'utilisateur. En outre, vous pouvez utiliser ngForm.$dirty pour envoyer un message à l'utilisateur seulement quand ils ont fait des changements.

j'ai écrit une directive angularjs que vous pouvez appliquer à n'importe quel formulaire qui guette automatiquement les changements et le message de l'utilisateur s'ils rechargent la page ou naviguer loin. @voir https://github.com/facultymatt/angular-unsavedChanges

nous espérons que vous trouverez cette directive utile!

9
répondu facultymatt 2013-08-22 15:46:49

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 , sont dépréciés à partir de 1.0 . Le nouveau code ui-router 1.0 utilise le $transitions service . Vous devez donc injecter $transitions dans votre component puis utiliser les transitions $.avant la méthode comme le code ci-dessous le démontre.

$transitions.onBefore({}, function(transition) {
  return confirm("Are you sure you want to leave this page?");
});

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

2
répondu Brent Matzelle 2016-12-28 19:14:40
$scope.rtGo = function(){
            $window.sessionStorage.removeItem('message');
            $window.sessionStorage.removeItem('status');
        }

$scope.init = function () {
            $window.sessionStorage.removeItem('message');
            $window.sessionStorage.removeItem('status');
        };

Recharger la page: à l'aide d'init

-1
répondu Srija Nakka 2017-08-08 15:07:12