我的一项服务中的onbeforeUnload
事件有以下回调。
在app.run
块中,我有:
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
})
现在假设事件在角度上是同步的,这段代码应该在窗口关闭时弹出窗口。但是,这会直接关闭我的窗口。
我的意图是每当用户关闭窗口时,我都会引发一个事件,看看我的控制器中是否有未保存的数据。如果有一些未保存的数据,浏览器不应该关闭并弹出,而如果没有未保存的数据,浏览器应该关闭。
我在做什么或者理解错了吗?
答案 0 :(得分:5)
在您的模块run
功能中,您必须以这种方式声明beforeunload
事件:
.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
事件的代码段。
注意:,根据您的浏览器,点击保存项目按钮后,代码片段无法正常工作,您尝试关闭此窗口。然后,您需要将代码粘贴到您自己的项目中。
其他信息
最近的HTML规范现在阻止了弹出消息的自定义,而是显示通用消息。
因此始终可以阻止导航,但不再可以指定自定义消息
这总是适用于IE11,但它不应该持续很长时间(直到下次更新)。
关于此的HTML规范: https://html.spec.whatwg.org/multipage/browsers.html#unloading-documents
Chrome / Safari文档有关此内容: 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>
&#13;