AngularJS Factory $ rootScope。$ on cleanup

时间:2014-11-12 20:09:47

标签: javascript angularjs angularjs-service angularjs-factory rootscope

如何从服务内部清除事件订阅$ rootScope。$?

我在AngularJS应用程序中的不同控制器中初始化了一个Factory,其中声明了$ rootScope。$ on事件订阅。我的问题是,当控制器被销毁时,事件不会被清除。我已经完成阅读并发现使用控制器和指令你可以在$ destroy上设置$ watch以进行清理,但是对于服务呢?你如何清理服务?

这是我问题的基本插图:http://plnkr.co/edit/dY3BVW。点击“创建孩子”'按下一堆时间来初始化一个子控制器,它将使用$ rootScope。$ on初始化工厂。点击“广播”后,当浏览器控制台打开时,您会看到一系列事件订阅被触发,子控制器被销毁后发生事件。

Plunker的片段:

// setup rootScope on in Factory and create multiple instances
// to show that event subscriptions are not cleaned up
// TODO: how do you cleanup in factory?
app.factory('HelloWorldFactory', function($rootScope) {

  // setup event subscription on initialization
  function HelloWorldFactory() {
    console.log('init helloWorldFactory');

    var rootScopeOn = $rootScope.$on('test', function() {
      console.log('test sub', Math.random());
    });
  }

  return HelloWorldFactory;
});

// child ctrl will init a new factory instance
app.controller('ChildCtrl', function($scope, HelloWorldFactory) {
  $scope.name = 'Child';

  var helloWolrdFactory = new HelloWorldFactory();
});

1 个答案:

答案 0 :(得分:4)

您可以在创建新事件之前终止哨兵。创建新控制器后,rootScopeOn变量将保持不变,因此每次重新初始化时都可以将其删除。

app.factory('HelloWorldFactory', function($rootScope) {

  var rootScopeOn;

  // setup event subscription on initialization
  function HelloWorldFactory() {
    console.log('init helloWorldFactory');
    if (typeof rootScopeOn === 'function') {
      rootScopeOn();
    }

    rootScopeOn = $rootScope.$on('test', function() {
      console.log('test sub', Math.random());
    });
  }

  return HelloWorldFactory;
});

// child ctrl will init a new factory instance
app.controller('ChildCtrl', function($scope, HelloWorldFactory) {
  $scope.name = 'Child';

  var helloWolrdFactory = new HelloWorldFactory($scope);
});