AngularJS Factory $ rootScope. $ On Cleanup

How to clear $ rootScope. $ from subscribing to events from within the service?

I have a Factory that is initialized in different controllers of my AngularJS app where the $ rootScope subscription is declared. $ on event. My problem is when the controller is destroyed the event is not cleared. I did a read and found that with controllers and directives, you can set $ watch to $ destroy to clean up, but what about services? How do you clean up services?

Here's a basic Plunker for my problem: http://plnkr.co/edit/dY3BVW . Click the "create child" button for a bunch of time to initialize the child controller, which initializes the Factory with $ rootScope. $ On. When the browser console opens when you click "broadcast", you will see the event subscription started, the event after the destruction of the child controllers.

Snippet from 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();
});

      

+3


source to share


1 answer


You can kill a sentinel before creating a new event. The rootScopeOn variable will remain intact after creating new controllers, so you can kill it every time you initialize it again.



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);
});

      

+4


source







All Articles