AngularJS window.onbeforeunload in one controller is being triggered on another controller
这是我的问题,我有两个视图(View1和View2)以及每个视图的控制器(Ctrl1和Ctrl2)。在View1中,我试图在用户意外离开页面之前警告用户而不保存更改。
我正在使用window.onbeforeunload,效果很好,但是我的问题是,即使我仅在一个控制器上拥有onbeforeunload,该事件似乎也在第二个控制器中触发!但是我什至没有那个活动。当用户离开页面并且有未保存的更改时,如果用户关闭了警报并离开了页面,则他会被onbeforeunload警告,如果用户尝试现在离开另一个视图,则他将返回第二个视图,我们还会警告您未保存的更改!如果不是这样的话!为什么会这样呢?
我也使用$ locationChangeStart,它工作得很好,但是仅当用户更改路线时,而不是在刷新浏览器,点击"后退"或尝试关闭它时,这就是为什么我被迫使用onbeforeunload(如果您有更好的方法,请告诉我)。任何帮助或更好的方法将不胜感激!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //In this controller I check for window.onbeforeunload app.controller("Ctrl1", function ($scope, ...)){ window.onbeforeunload = function (event) { //Check if there was any change, if no changes, then simply let the user leave if(!$scope.form.$dirty){ return; } var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?'; if (typeof event == 'undefined') { event = window.event; } if (event) { event.returnValue = message; } return message; } //This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser $scope.$on('$locationChangeStart', function( event ) { if (!$scope.form.$dirty) return; var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?') if (!answer) { event.preventDefault(); } }); } //This other controller has no window.onbeforeunload, yet the event is triggered here too! app.controller("Ctrl2", function ($scope, ...)){ //Other cool stuff ... } |
我尝试使用$ location.path()检查当前路径,以仅在用户在我希望触发onb??eforeunload的视图中时警告用户,但这似乎有点"棘手",解决方案是不对另一个执行onbeforeunload控制器。
我在第一个中添加了$ location.path()!='/ view1',但这似乎对我来说并不正确,除了我不仅有两个视图,我还有多个视图,这样可以棘手的涉及更多的控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | app.controller("Ctrl1", function ($scope, ...)){ window.onbeforeunload = function (event) { //Check if there was any change, if no changes, then simply let the user leave if($location.path() != '/view1' || !$scope.form.$dirty){ return; } var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?'; if (typeof event == 'undefined') { event = window.event; } if (event) { event.returnValue = message; } return message; } //This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser $scope.$on('$locationChangeStart', function( event ) { if (!$scope.form.$dirty) return; var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?') if (!answer) { event.preventDefault(); } }); } |
当定义它的控制器超出范围时,请注销onbeforeunload事件:
1 2 3 | $scope.$on('$destroy', function() { delete window.onbeforeunload; }); |
我只是尝试了上述解决方案,但对我来说却没有用。 即使在控制台中手动键入
1 2 3 | $scope.$on('$destroy', function(e){ $window.onbeforeunload = undefined; }); |
对于使用angular-ui-router的用户,您可以使用
1 2 3 4 5 6 7 8 | $scope.$on('$stateChangeStart', function (event){ if (forbit){ event.preventDefault() } else{ return } }) |
作为对此的更新,对于任何使用angular-ui-router的人,我现在将$ transitions传递到您的控制器中并使用;
1 2 3 4 5 | $transitions.onStart({}, function ($transition) { $transition.abort(); //return false; }); |