0

Service

export class RandomServiceName implements ng.IServiceProvider {
  /* @ngInject */
  constructor(private $rootScope: ng.IRootScopeService) {
  }

  public $get(): RandomServiceName {
    return this;
  }

  doStuff() {
      this.$rootScope.$broadcast('hello', 'world');
  }
}

Controller

import {RandomServiceName} from './random_service_name.ts';

export class RandomController {
  /* @ngInject */
  constructor(private $rootScope: ng.IRootScopeService,
              private $log: ng.ILogService,
              private RandomServiceName: RandomServiceName) {
      this.RandomServiceName.doStuff();
      this.$rootScope.$on('hello', (event: ng.IAngularEvent, data: string) =>
          this.$log.info(`Event '${event.name}' caught with data ${data}`)
      );
  }
}

But that doesn't make sense, because the constructor is only called once (per initiation)... :\

A T
  • 13,008
  • 21
  • 97
  • 158
  • This is precisely why it does make sense. Why would you want to subscribe several times to the same event type? Please elaborate. What do you want to achieve? – JB Nizet Apr 14 '16 at 16:34
  • Many things use that service and call `doStuff`. Wherever that happens I want to react within `$on` – A T Apr 14 '16 at 16:37
  • Well, that's what the code does. Every time the event is broadcasted by the service, the callback function will be executed, and the event will thus be logged. Let's say you want to be notified by email when a new question is asked on Stackoverflow. How many times do you need to configure your preferences in order to achieve that? Just once, right?. But you will nevertheless receive several emails, right? Same here. You ask the rootScope to notify you of an event type once, and every time such an event is broadcasted, the rootScope notifies you. – JB Nizet Apr 14 '16 at 16:43
  • That said, you should call $on() on the $scope that is created for your controller, not on $rootScope. – JB Nizet Apr 14 '16 at 16:45
  • Are you saying that you want the hello event to be listened to globally across your app and for the same function to be called when it gets fired? – Ed Spencer Apr 14 '16 at 16:52
  • You wrote ` constructor(private $rootScope: ng.IRootScopeService...)` the keyword `private` in the constructor will put your `$rootScope` on your controller scope as class variable. So you can use `this.$rootScope` everywhere in your controller. – kabaehr Apr 14 '16 at 17:42

1 Answers1

0

You put $on in your controller and the you also $off using your controller's scope's $destroy event.

More : https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$destroy

Events

$destroy

Broadcasted when a scope and its children are being destroyed. Note that, in AngularJS, there is also a $destroy jQuery event, which can be used to clean up DOM bindings before an element is removed from the DOM.

Also:

Personal Opinion: Events can make your code quite hard to reason about.

basarat
  • 261,912
  • 58
  • 460
  • 511