Search code examples
javascriptangularjsdirectivebroadcast

AngularJS broadcast event is not listening inside directive


I'm trying to export some data to xls, pdf, get a example on by using AngularJS $broadcast events - plunker.

This is my controller:

admin.controller('ctrlReuniaoRelatorioDetalhe', ['$scope', '$http', '$controller', '$window', 'baseURL', 'blockUI', function($scope, $http, $controller, $window, baseURL, blockUI) {
  angular.extend(this, $controller('BaseListController', {
    $scope: $scope
  }));

  $scope.Formulario = "ReuniaoRelatorioDetalheViewModelForm";
  $scope.dataemissao = new Date();
  ctrlReuniaoRelatorioDetalhe = $scope;
  ctrlReuniaoRelatorioDetalhe.http = $http;


  $scope.reportData = [{
    "EmployeeID": "1234567",
    "LastName": "Lastname",
    "FirstName": "First name",
    "Salary": 1000
  }, {
    "EmployeeID": "11111111",
    "LastName": "Lastname 1",
    "FirstName": "First name 1",
    "Salary": 2000
  }, {
    "EmployeeID": "222222222",
    "LastName": "Lastname 2",
    "FirstName": "First name 2",
    "Salary": 3000
  }, {
    "EmployeeID": "333333333",
    "LastName": "Lastname 3",
    "FirstName": "First name 3",
    "Salary": 4000
  }];

  $scope.exportAction = function(option) {

    switch (option) {
      case 'pdf':
        $scope.$broadcast('export-pdf', {});
        break;
      case 'excel':
        $scope.$broadcast('export-excel', {});
        break;
      case 'doc':
        $scope.$broadcast('export-doc', {});
        break;
      case 'csv':
        $scope.$broadcast('export-csv', {});
        break;
      default:
        console.log('no event caught');
    }
  }
}]);

This is my directive:

 app.directive('exportTable', function() {
   var link = function($scope, elm, attr) {
     $scope.$on('export-pdf', function(e, d) {
       elm.tableExport({
         type: 'pdf',
         escape: false
       });
     });
     $scope.$on('export-excel', function(e, d) {
       elm.tableExport({
         type: 'excel',
         escape: false
       });
     });
     $scope.$on('export-doc', function(e, d) {
       elm.tableExport({
         type: 'doc',
         escape: false
       });
     });
     $scope.$on('export-csv', function(e, d) {
       elm.tableExport({
         type: 'csv',
         escape: false
       });
     });
   }
   return {
     restrict: 'C',
     link: link
   }
 });

I dont have any idea why $scope.$on() in my directive is not listening to my event. The $scope.exportAction is working but when "broadcast" is fired, nothing happends.


Solution

  • You need to cover/analyze two scenarios here. Please check both working examples in this answer and make yourself understood how broadcasting in AngularJS works.

    This links will help you to dig deeper into broadcast events:


    Use $scope.$broadcast() when your directive is a child of your controller where the event is fired. -> demo fiddle

    AngularJS application

    var myApp = angular.module('myApp',[]);
    
    myApp.controller('MyCtrl', function ($scope) {
        $scope.name = 'Superhero';
    
        $scope.clickMe = function () {
           $scope.$broadcast('test');
        }
    });
    
    myApp.directive('myDirective', function () {
        return {
          restrict: 'A',
          link: function (scope, element, attrs) {
            scope.$on('test', function () {
                console.log('hello world');
            })
          }
        }
    });
    

    View

    <div ng-controller="MyCtrl">
      <button ng-click="clickMe()">
        Click Me
      </button>
      <div my-directive></div>
    </div>
    

    Use $rootScope.$broadcast() when your directive is not a child of your controller where the event is fired. -> demo fiddle

    AngularJS application

    var myApp = angular.module('myApp',[]);
    
    myApp.controller('MyCtrl', function ($rootScope, $scope) {
        $scope.name = 'Superhero';
    
        $scope.clickMe = function () {
           $rootScope.$broadcast('test');
        }
    });
    
    myApp.directive('myDirective', function () {
        return {
          restrict: 'A',
          link: function (scope, element, attrs, $rootScope) {
            scope.$root.$on('test', function () {
                console.log('hello world');
            })
          }
        }
    });
    

    View

    <div ng-controller="MyCtrl">
      <button ng-click="clickMe()">
        Click Me
      </button>
    </div>
    <div my-directive></div>