Reputation: 25062
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
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
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
Reputation: 8427
It is $rootScope.$broadcast. If it were to broadcast only to the current scope, your controller wouldn't see it.
Upvotes: 1