Search code examples
angularjsangularjs-scopeangularjs-routingangularjs-controller

Unable to broadcast event from parent controller in angularjs


I have a two controller having parent-child relationship:

This is the route for parent controller:

angular.module('app')
  .config(function ($stateProvider) {
    $stateProvider
      .state('data-show', {
        url: '/data',
        templateUrl: 'app/data.html',
        controller: 'DataCtrl'
      });
  });

This is the HTML for parent controller:

<div class="block-header">
   ...
   ...
    <div ng-include="'components/child_page.html'"></div>
</div>

Code for parent controller:

angular.module('app')
  .controller('DataCtrl', function ($scope) {

      $rootScope.$broadcast('someEvent', [1,2,3]);
 });

The child controller is part of child_page.html page, which is included in parent page using ng-include tag as shown above.

This is how child controller looks:

angular.module('app')
    .controller('childCtrl', function ($scope) {

        $scope.$on('someEvent', function(event, mass) {
            console.log('EVENT CALLED');
        });
  });

HTML for child page:

<div ng-controller="childCtrl">
    <div id="myGrid"></div>
</div>

But even though I am broadcasting the event from parent controller, the event is not getting called in child page.


Solution

  • From the comments:

    I would bet the reason is that the child controller is not loaded yet when the event is broadcasted - so there is noone there to listen.

    And it seems to be verified:

    before I broadcast the event, I am writing to console "broadcasting" & on the first line of child controller, I am writing to "console child controller is loaded". If I check console now, I first see "broadcasting" message and then "child controller is loaded".

    Looking at the docs of ng-include, it emits the $includeContentLoaded event when the content is loaded. So a first approach is:

    // parent controller:
    $rootScope.$on('$includeContentLoaded', function() {
        $rootScope.$broadcast('someEvent', [1,2,3]);
    });
    

    It could be optimized later on using the parameters of the event.