How to listen to scope events in Angular 1.5 component?
Asked Answered
H

1

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!

Handpick answered 26/8, 2016 at 4:42 Comment(4)
Possible duplicate of AngularJs 1.5 - Component does not support Watchers, what is the work around?Mama
@Mama 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!Handpick
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.Mama
@Mama 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?Handpick
M
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.

Mama answered 28/8, 2016 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.