无法使用 Angular 服务处理 onbeforeunload 事件
Unable to handle onbeforeunload event using Angular Service
我的一项服务中的 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
})
现在假设事件在 angular 中是同步的,这段代码应该会在 window 关闭时给我一个弹出窗口。但是,这直接关闭了我的 window.
我的意图是每当用户关闭 window 时,我都会引发一个事件并查看我的控制器中是否有任何未保存的数据。如果有一些未保存的数据,浏览器不要关闭并弹出,如果没有未保存的数据,浏览器应该关闭。
我是不是做错了或理解错了?
在您的模块 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
};
}]);
这是将 onbeforeunload
事件与 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 规范现在阻止自定义弹出消息,而是显示通用消息。
因此始终可以阻止导航,但不再可能指定自定义消息
这始终适用于 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>
我的一项服务中的 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
})
现在假设事件在 angular 中是同步的,这段代码应该会在 window 关闭时给我一个弹出窗口。但是,这直接关闭了我的 window.
我的意图是每当用户关闭 window 时,我都会引发一个事件并查看我的控制器中是否有任何未保存的数据。如果有一些未保存的数据,浏览器不要关闭并弹出,如果没有未保存的数据,浏览器应该关闭。
我是不是做错了或理解错了?
在您的模块 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
};
}]);
这是将 onbeforeunload
事件与 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 规范现在阻止自定义弹出消息,而是显示通用消息。
因此始终可以阻止导航,但不再可能指定自定义消息
这始终适用于 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>