无法使用Angular Service处理onbeforeunload事件 [英] Unable to handle onbeforeunload event using Angular Service
问题描述
我的一个服务中的 onbeforeUnload
事件有以下回调。
在我的 app.run
块中,我有:
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;
此方法在服务中:
this.beforeWindowClose = function (event) {
var currentState = $state.current.name;
if (currentState !== constant.LOGOUT) {
$rootScope.$broadcast("close");
if (Utilities.isSavePending)
event.returnValue = constant.MSG;
}
}
在我的控制器中我有:
$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??
推荐答案
在你的模块运行
函数中,你必须以这种方式声明 beforeunload
事件:
In 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
};
});
不是这样的:
.run(['$window', 'Utilities', function($window, Utilities) {
window.onbeforeunload = function() {
// Place code here
};
}]);
这是一个片段使用Angular的 onbeforeunload
事件。
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.
其他信息
最近的HTML规范现在阻止了弹出消息的自定义,而是显示了一般信息。
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
这总是适用于IE11,但它不能持续很长时间(直到下次更新)。
This always works on IE11 but it should not last long (until the next update).
关于此的HTML规范:
https://html.spec.whatwg.org/multipage/browsers.html#unloading-documents
HTML Specs about this : https://html.spec.whatwg.org/multipage/browsers.html#unloading-documents
Chrome / Safari文档关于此:
https://www.chromestatus.com/feature/5349061406228480
Chrome/Safari docs about this : https://www.chromestatus.com/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.com/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>
这篇关于无法使用Angular Service处理onbeforeunload事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!