无法使用Angular Service

时间:2017-05-23 11:02:49

标签: javascript angularjs javascript-events onbeforeunload

我的一项服务中的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
        })

现在假设事件在角度上是同步的,这段代码应该在窗口关闭时弹出窗口。但是,这会直接关闭我的窗口。

我的意图是每当用户关闭窗口时,我都会引发一个事件,看看我的控制器中是否有未保存的数据。如果有一些未保存的数据,浏览器不应该关闭并弹出,而如果没有未保存的数据,浏览器应该关闭。

我在做什么或者理解错了吗?

1 个答案:

答案 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;
&#13;
&#13;