admin管理员组文章数量:1327667
I have the following callback for my onbeforeUnload
event in one of my service.
In my app.run
block I have:
window.onbeforeunload = Services.beforeWindowClose;
and this method is in a service:
this.beforeWindowClose = function (event) {
var currentState = $state.current.name;
if (currentState !== constant.LOGOUT) {
$rootScope.$broadcast("close");
if (Utilities.isSavePending)
event.returnValue = constant.MSG;
}
}
In my controllers I have :
$scope.$on("close", function () {
Utilities.isSavePending = vm.save; //sets it to true
})
Now given the events are synchronous in angular, this code should give me a popup on window close. However,this directly closes my window.
My intention is that whenever the user closes window, I raise an event and see if there is any unsaved data in my controller. If there is some unsaved data, the browser should not close and give a popup, while if there is no unsaved data, the browser should close.
Am I doing or understanding something wrong?
I have the following callback for my onbeforeUnload
event in one of my service.
In my app.run
block I have:
window.onbeforeunload = Services.beforeWindowClose;
and this method is in a service:
this.beforeWindowClose = function (event) {
var currentState = $state.current.name;
if (currentState !== constant.LOGOUT) {
$rootScope.$broadcast("close");
if (Utilities.isSavePending)
event.returnValue = constant.MSG;
}
}
In my controllers I have :
$scope.$on("close", function () {
Utilities.isSavePending = vm.save; //sets it to true
})
Now given the events are synchronous in angular, this code should give me a popup on window close. However,this directly closes my window.
My intention is that whenever the user closes window, I raise an event and see if there is any unsaved data in my controller. If there is some unsaved data, the browser should not close and give a popup, while if there is no unsaved data, the browser should close.
Am I doing or understanding something wrong?
Share Improve this question edited Feb 17, 2020 at 16:46 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 23, 2017 at 11:02 Saurabh TiwariSaurabh Tiwari 5,16111 gold badges50 silver badges90 bronze badges 6- Are you saying you don't get the browser default confirm dialog? Expected behavior and problem is not very clear – charlietfl Commented May 23, 2017 at 11:06
-
Also, try to
return constant.MSG
, cause some browsers need this – dloeda Commented May 23, 2017 at 11:08 - yes charlietfl, you got me correct. I am not getting the popup. The expected behaviour is to get popup only when isSavePending turns out to be true. – Saurabh Tiwari Commented May 23, 2017 at 11:12
- @dloeda returning msg didn't help either. – Saurabh Tiwari Commented May 23, 2017 at 11:16
-
Did you double check both conditions are correct and
event.returnValue = constant.MSG;
code is executing? – dloeda Commented May 23, 2017 at 11:19
1 Answer
Reset to default 6In your module run
function, you must declare beforeunload
event this way :
.run(['$window', 'Utilities', function($window, Utilities) {
$window.addEventListener('beforeunload', function(e)
// Place code here
};
});
NOT this way :
.run(['$window', 'Utilities', function($window, Utilities) {
window.onbeforeunload = function() {
// Place code here
};
}]);
Here is a snippet to use onbeforeunload
event with Angular.
Note: depending on your browser, snippet won't work after you click Save item button and you try to close this window. You'll then need to paste the code in your own project.
Additional information
Recent HTML specifications now prevent customization of the popup message, a generic message is displayed instead.
It is therefore always possible to prevent navigation but it is no longer possible to specify a custom message
This always works on IE11 but it should not last long (until the next update).
HTML Specs about this : https://html.spec.whatwg/multipage/browsers.html#unloading-documents
Chrome/Safari docs about this : https://www.chromestatus./feature/5349061406228480
angular.module('app', []);
angular
.module('app')
.controller('ExampleController', ['$scope', 'Utilities', 'ItemService', function($scope, Utilities, ItemService) {
// Expose Utilities to make pending state available in template
$scope.Utilities = Utilities;
// Use item service to save our item
$scope.save = function() {
ItemService.saveItem();
}
$scope.fireCloseEvent = function() {
$scope.$emit('close');
}
$scope.$on('close', function(event) {
Utilities.toggleSavePending();
});
}])
.factory('ItemService', ['Utilities', function(Utilities) {
return {
saveItem: function() {
// ...
// Toggle global save pending state
Utilities.toggleSavePending();
}
}
}])
.factory('Utilities', function() {
var savePending = false;
return {
toggleSavePending: function() {
savePending = !savePending;
},
isSavePending: function() {
return savePending;
}
}
})
.run(['$window', 'Utilities', function($window, Utilities) {
$window.addEventListener('beforeunload', function(e) {
// If save pending state is truthy, prevent browser window from closing
if (Utilities.isSavePending()) {
var message = 'Warning! Save pending...';
e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
});
}]);
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare./ajax/libs/angular.js/1.6.4/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="ExampleController">
<button ng-click="save()" ng-disabled="Utilities.isSavePending()">Save item</button>
<button ng-click="fireCloseEvent()">Fire Close Event</button>
<div ng-if="Utilities.isSavePending()">A message should be displayed when you close the window</div>
</body>
</html>
本文标签: javascriptUnable to handle onbeforeunload event using Angular ServiceStack Overflow
版权声明:本文标题:javascript - Unable to handle onbeforeunload event using Angular Service - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742226000a2436327.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论