这是我的问题,我有两个视图(View1和View2)和每个视图的控制器(Ctrl1和Ctrl2)。在View1中,我试图在用户意外离开页面之前警告用户而不保存更改。
我正在使用window.onbeforeunload,它工作正常,但我的问题是,即使我只在一个控制器上进行onbeforeunload,事件似乎也在第二个控制器中触发!但我在那里甚至没有那件事。当用户离开页面并且有未保存的更改时,他会被onbeforeunload警告,如果用户关闭警报并离开页面,他是否会被带回第二个视图,如果用户现在试图离开这个其他视图,我们也会收到有关未保存更改的警告!当情况不是这样的时候!为什么会这样?
我还使用了$ locationChangeStart,它运行得很好,但只有当用户更改路线时,才会刷新浏览器,点击“返回”或尝试关闭它,这就是为什么我被迫使用onbeforeunload(如果你有更好的方法,请告诉我)。任何帮助或更好的方法将不胜感激!
//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()来检查当前路径,仅在用户处于视图中时警告用户我想要触发onbeforeunload,但这似乎有点' hacky'解决方案是根本不在另一个控制器上执行onbeforeunload。
我在第一个似乎有用的地方添加了$ location.path()!=' / view1' ,但它对我来说似乎不对,除此之外我不会只有两个观点,我有几个观点,如果涉及更多的控制器,这会变得棘手:
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();
}
});
}
答案 0 :(得分:23)
当定义它的控制器超出范围时,取消注册onbeforeunload事件:
$scope.$on('$destroy', function() {
delete window.onbeforeunload;
});
答案 1 :(得分:20)
我只是尝试了上述解决方案,但这并不适合我。即使在控制台中手动键入delete window.onbeforeunload
也不会删除该功能。我需要将属性设置为undefined。
$scope.$on('$destroy', function(e){
$window.onbeforeunload = undefined;
});
答案 2 :(得分:8)
对于那些使用angular-ui-router的人,您会使用$stateChangeStart
代替$locationChangeStart
,例如。
$scope.$on('$stateChangeStart', function (event){
if (forbit){
event.preventDefault()
}
else{
return
{
})
答案 3 :(得分:2)
作为对此的更新,对于任何使用angular-ui-router的人,我现在将$ transition传递给你的控制器并使用;
$transitions.onStart({}, function ($transition)
{
$transition.abort();
//return false;
});