首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >一个控制器中的AngularJS window.onbeforeunload正在另一个控制器上触发

一个控制器中的AngularJS window.onbeforeunload正在另一个控制器上触发
EN

Stack Overflow用户
提问于 2014-08-28 01:29:33
回答 4查看 41.4K关注 0票数 23

这就是我的问题,我有两个视图(View1和View2),每个视图(Ctrl1和Ctrl2)都有一个控制器。在View1中,我试图在用户未保存更改的情况下意外离开页面之前发出警告。

我使用的是window.onbeforeunload,它工作得很好,但我的问题是,即使我只在一个控制器上有onbeforeunload,事件似乎也会在第二个控制器中触发!但是我甚至没有那个活动在里面。当用户离开一个页面并且有未保存的更改时,他会收到onbeforeunload的警告,如果用户忽略警告并离开页面,他会返回到第二个视图吗?如果用户现在试图离开另一个视图,我们也会收到有关未保存更改的警告!但事实并非如此!为什么会发生这种情况?

我也在使用$locationChangeStart,它工作得很好,但只有当用户改变路线时,而不是当他们刷新浏览器,点击“上一步”或试图关闭它时,这就是为什么我被迫使用onbeforeunload (如果你有更好的方法,请让我知道)。任何帮助或更好的方法都将不胜感激!

代码语言:javascript
复制
//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的视图中时才发出警告,但这似乎有点“老生常谈”解决方案是根本不在另一个控制器上执行onbeforeunload。

我在第一个中添加了$location.path() != '/view1',这看起来不错,但对我来说似乎不正确,而且我不仅有两个视图,还有几个视图,涉及更多的控制器,这会变得很棘手:

代码语言:javascript
复制
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();
    }
  });
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-08-28 01:55:28

当定义onbeforeunload事件的控制器超出范围时,注销onbeforeunload事件:

代码语言:javascript
复制
$scope.$on('$destroy', function() {
    delete window.onbeforeunload;
});
票数 24
EN

Stack Overflow用户

发布于 2014-12-18 03:02:09

我刚刚尝试了上面的解决方案,但这对我来说不起作用。即使在控制台中手动输入delete window.onbeforeunload也不会删除该函数。我需要将该属性设置为undefined。

代码语言:javascript
复制
$scope.$on('$destroy', function(e){
  $window.onbeforeunload = undefined;
});
票数 21
EN

Stack Overflow用户

发布于 2015-03-26 18:03:04

对于那些使用angular-ui-router的用户,您将使用$stateChangeStart而不是$locationChangeStart,例如

代码语言:javascript
复制
$scope.$on('$stateChangeStart', function (event){
  if (forbit){
    event.preventDefault()
  }
  else{  
    return
  }
})
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25533513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档