当用户离开页面时在angularjs中显示警报

iJa*_*ade 58 javascript model-view-controller angularjs angularjs-directive

我是一个有角度的新蜜蜂.我正在尝试编写一个验证,在用户尝试关闭浏览器窗口时提醒用户.

我的页面v1和v2上有2个链接.当点击指向特定页面的链接时.这是重定向到v1和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'});
}]);
Run Code Online (Sandbox Code Playgroud)

当用户点击v1"他即将离开v1,如果他想继续"并且点击v2时,我想弹出一条消息.任何关于如何实现这一点的指示将不胜感激.

我在这里得到了一个答案,但它会在每个时间间隔后弹出消息.

更新的代码;

控制器

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 = [];
Run Code Online (Sandbox Code Playgroud)

Sch*_*tod 105

确认对话的代码可以这样写得更短:

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

  • 使用Angular ui-router时:使用'$ stateChangeStart'而不是'$ locationChangeStart' (32认同)
  • 这是一个更清洁的解决方案 另一个让我进入无限循环的导航确认...... (5认同)
  • 遗憾的是,当您使用路由服务时,这不起作用,每次位置更改时都会触发事件. (5认同)
  • 我是唯一一个在打开页面时出现此代码的人,而不是当我离开时? (3认同)

Yai*_*vet 43

让我们分开你的问题,你要问两件事:

1.

我正在尝试编写一个验证,在用户尝试关闭浏览器窗口时提醒用户.

2.

当用户点击v1"他即将离开v1,如果他想继续"并且点击v2时,我想弹出一条消息.

对于第一个问题,请这样做:

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;
}
Run Code Online (Sandbox Code Playgroud)

对于第二个问题,请这样做:

您应该处理$locationChangeStart事件以便连接到查看转换事件,因此使用此代码来处理控制器中的转换验证:

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


Chr*_*ies 22

这是我使用的指令.它在表单卸载时自动清理.如果要阻止提示被触发(例如,因为您已成功保存表单),请调用$ scope.FORMNAME.$ setPristine(),其中FORMNAME是您要阻止提示的表单的名称.

.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();
                }
            });
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

  • 我不得不在FF 31.0中使用`$(window).bind('beforeunload',doPrompt);`而不是`window.addEventListener('beforeunload',areYouSurePrompt);``(以及`unbind` for"removeEventListener`)原因是本机`window`调用不起作用(而`window.onbeforeunload = function(){return"肯定?";}`工作)?!另外从我所知道的,`$ locationChangeStart`永远不会被解雇,并且考虑使用`onbeforeunload`这个块真的有必要吗? (2认同)

小智 9

正如你在前面已经发现,可以使用的组合window.onbeforeunload$locationChangeStart用户信息.此外,您可以利用ngForm.$dirty仅在用户进行更改时向用户发送消息.

我编写了一个angularjs指令,您可以将其应用于任何会自动监视更改的表单,并在用户重新加载页面或离开时向用户发送消息.@see https://github.com/facultymatt/angular-unsavedChanges

希望你发现这个指令很有用!