53

我是一个新的角色js。我试图编写一个验证,当他试图关闭浏览器窗口时提醒用户。当用户离开页面时显示在angularjs中的警报

我在我的页面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'}); 
}]); 

我想弹出一个消息,当用户点击V1说,“他是即将从V1离开,如果他希望继续”和同在点击在v2上。 任何关于如何实现这一点的指针,将不胜感激。

我得到了一个答案here,但它在每个时间间隔后弹出消息。

更新后的代码;

控制器

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 = []; 
+11

我相信你想要的术语是 “[新手](http://www.urbandictionary.com/define.php?term=newbie)”。除非你真的是一只意大利蜜蜂。 – 2015-12-15 16:22:27

回答

100

代码Ë确认对话框可以写成短这样​​:

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

这是一个更清洁的解决方案。另一个导致我导航无限循环确认... – wakandan 2014-04-03 04:24:35

+1

还有一个标准JavaScript事件处理程序,它监听资源卸载。即当它不是一个SPA应用程序。监听器可以分配给'window.onbeforeunload'。 – Eugene 2015-03-02 08:45:57

+5

不幸的是,当你使用路由服务时,这是行不通的,每当位置发生变化时触发事件。 – user544262772 2015-05-20 09:11:12

41

让独立你的问题,你问的是两种不同的东西:

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; 
} 

而对于第二个问题,做这种方式:

你应该以挂钩处理$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(); 
     } 
    }); 
} 
+0

我想要一个提醒,通知用户他即将离开该页面,他真的想继续吗?希望我很清楚。 – iJade 2013-02-11 12:09:14

+0

@jade请看我更新的答案。 – 2013-02-11 12:24:01

+0

我应该在哪里放这个代码。不过,我是一个完整的angularjs新bie? – iJade 2013-02-11 12:24:47

9

正如你上面发现了,你可以使用的window.onbeforeunload$locationChangeStart组合来消息的用户。另外,您可以利用ngForm.$dirty仅在用户进行更改时向用户发送消息。

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

希望您觉得这个指令很有用!

19

这是我使用的指令。当表单被卸载时它会自动清理自己。如果您想阻止提示(例如,因为您成功保存了表单),请调用$ 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(); 
       } 
      }); 
     } 
    }; 
}]); 
+2

我不得不在FF中使用'$(window).bind('beforeunload',doPrompt);'而不是'window.addEventListener('beforeunload',areYouSurePrompt);'(和'unbind'' removeEventListener') 31.0出于任何原因,原生'window'调用不工作(而'window.onbeforeunload = function(){return“sure?”;}'工作)?!另外从我可以告诉,'$ locationChangeStart'永远不会开火,并考虑使用'onbeforeunload'这个块真的有必要吗? – Campbeln 2014-08-27 01:49:05

+0

@Campbeln upvoted的提示,上面的代码也没有在Chrome42上工作,我不得不如你所说的做。 – 2015-04-24 03:38:04

2

其他的例子做工精细的老版本用户界面路由器(> = 0.3.X),但所有国家的活动,如$stateChangeStart,是deprecated as of 1.0。新的UI路由器1.0代码使用$transitions service。因此,您需要将$transitions注入您的组件,然后使用$transitions.onBefore方法,如下面的代码所示。

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

这只是一个超级简单的例子。 $transitions服务可以接受更复杂的响应,如承诺。有关更多信息,请参阅HookResult type

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

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

刷新页面:在使用init

相关问题