7

I'm in the middle of migrating code from Angular 1.3 to Angular 1.5 components and ES6 controllers. I tried to find something here on SO, but not helpful enough. Suggestions required on how to watch events on scope other than the way mentioned below. Or how to trigger scope events from the directive. Also please suggest the correct way of doing so, if an alternative exists.

Angular 1.3

angular
.module('test')
.directive('test', function() {
    return {
        link: function(scope) {
            scope.$on('$stateChangeStart', function(event, toState, toParams) {
                //logic goes here..
            });
        }
    }
});

Angular 1.5/ ES6

class TestController {
    /* @ngInject */
    constructor($scope) {
        this._$scope = $scope;
    }

    $onInit() {
        this._$scope.$on('$stateChangeStart', (event, toState, toParams) => {
            //logic goes here
        });
    }
}

angular
.module('test')
.component('test', {
    controller: TestController
});

Edit:

Interested in an alternative for $on and not $watch here, cause $onChange can replace $watch when you are just watching variables. I want to listen to scope events, as not 100% of the angular 1.3 code can be migrated to 1.5, I still have directives triggering events on scope!

Ashwin Aggarwal
  • 649
  • 8
  • 21
  • Possible duplicate of [AngularJs 1.5 - Component does not support Watchers, what is the work around?](http://stackoverflow.com/questions/35534479/angularjs-1-5-component-does-not-support-watchers-what-is-the-work-around) – georgeawg Aug 26 '16 at 04:54
  • @georgeawg I'm interested in an alternative for $on and not $watch here, cause $onChange can replace $on when you are just watching variables. I want to listen to scope events, as not 100% of the angular 1.3 code can be migrated to 1.5, I still have directives triggering events on scope! – Ashwin Aggarwal Aug 26 '16 at 08:14
  • The alternative to triggering events on scope is to use Expression Binding to communicate events from component to parent. And use one-way binding to communicate events the other way from parent to child component. – georgeawg Aug 26 '16 at 08:33
  • @georgeawg but still parent has to listen to scope event? Is there any way I can just not use $scope.$on and still listen to route change events? or any other event triggered by third party component on $rootscope? – Ashwin Aggarwal Aug 26 '16 at 09:15

1 Answers1

3

Scope events can be converted to RX observables in a service.

 app.factory("rxLocationChangeStart", function($rootScope, rx) {
     var rxLocationChangeStart = new rx.Subject();
     $rootScope.$on("$locationChangeStart", function() {
       rxLocationChangeStart.onNext(arguments);
     });
     return rxLocationChangeStart;
 })

Then a component can subscribe to those events:

 app.component("locationMonitor", {
       scope: {},
       template: ['<p>oldPath={{$ctrl.oldPath}}</p>',
                  '<p>newPath={{$ctrl.newPath}}</p>'].join(''),
       controller: function (rxLocationChangeStart) {
         var $ctrl = this;
         var subscr = rxLocationChangeStart.subscribe(function(data) {
             console.log("locationChangeStart ", data);
             $ctrl.newPath = data[1];
             $ctrl.oldPath = data[2];
         });
         this.$onDestroy = function() {
           subscr.dispose();
         };
       }
 })

Angular 2 replaces the scope event bus with RX Observables. Converting scope events to RX Observables provides an easy migration path from AngularJS to Angular 2.

The DEMO on PLNKR.

georgeawg
  • 48,608
  • 13
  • 72
  • 95