jhamm
jhamm

Reputation: 25062

My controller is not catching the event sent from a directive

I have a directive that broadcasts an event when a table row gets clicked. Here is the directive:

angular.module('app').directive('encounterItemTable', function () {
  return {
    restrict: 'A',
    replace: true,
    templateUrl: 'views/encounter.item.table.html',
    scope: {
      encounters : '='
    },

    link: function(scope) {
      scope.getSelectedRow = function(index) {
        scope.$broadcast('selectedRow', { rowIndex: index });
      };
    }
  };
});

Here is the markup that calls the getSelectedRow

<tr  ng-class="{selected: $index==selectedIndex}" ng-repeat="encounter in encounters | filter:search" data-id="{{encounter.id}}" ng-click="getSelectedRow($index)">

My getSelectedRow() function gets called when the row gets clicked. The index is correct. The controller on the other hand never hears anything. Here is the code in the controller.

  $scope.$on('selectedRow', function(event, data) {
    $scope.selectedIndex = data.rowIndex;
    $scope.selectedEncounter = $scope.encounters[data.rowIndex];
  });

Why would the controller not hear the event? What am I missing?

Upvotes: 1

Views: 289

Answers (3)

craigb
craigb

Reputation: 16907

I use $rootScope.$broadcast(event, data). I use events to decouple components i.e. components emitting events and listeners for events don't need to know about each other.

In your case where the event could reasonably contained to the component (directive) then you have to care about where in the DOM the relative positions of the listener/emitter are. I haven't run into this myself so generally use $rootScope.$broadcast() another benefit being any component in the app can listen to these events so something in a sidebar could update in relation to the events from the table (which probably not be in the same DOM hierarchy)

Upvotes: 1

charlietfl
charlietfl

Reputation: 171700

$broadcast sends events down to children. directive is nested within controller so need to send event up to a parent. Use scope.$emit to push events up through parents. Read the section in scope docs titled Scope Events Propagation

Upvotes: 1

Zack Argyle
Zack Argyle

Reputation: 8427

It is $rootScope.$broadcast. If it were to broadcast only to the current scope, your controller wouldn't see it.

Upvotes: 1

Related Questions