devdropper87
devdropper87

Reputation: 4207

Is it possible to $broadcast inside an $on? angularjs

I am in a parent controller to three different directives and am trying to broadcast down to children (the directives' controller) on an event.

I tried the following in the parent controller, which did not work.

 $scope.$on('tracking', function(e, data){
    //set it to open by default since that is the default case.
    if($scope.switchBackToOpen === undefined) {
      $scope.switchBackToOpen = true;
    }
    $scope.switchBackToOpen = data;
    $scope.$broadcast('switch back', $scope.switchBackToOpen);
  });

Since this didn't work, I did the following in my directive's controller instead of listening for the above broadcast:

vm.func = function(){
      if($scope.$parent.switchBackToOpen) {
       //communicate with a sibling directive
        $scope.$root.$broadcast('set status back to open');
      }

    };

If a $broadcast isn't possible inside an $on what's the most angular way to solve this problem?

EDIT for more structure of parent/children relationships:

When a div is clicked in one nested directive, I am trying to communicate up to the parent controller to capture whether that was the 'open' page or not via a variable inside the parent controller. I then want to send down the variable from this parent controller and let all nested directives have access to it (my second block of code is the directive that I want to have access to the parent controllers variable).

Upvotes: 1

Views: 341

Answers (1)

You won't want to broadcast an event to travel through scopes and caught in parent. Instead you would love to bind variables of parent to child directive. You can do that even if your directive has isolate scope.

Lets assume your html is like this :

<div ng-controller='parentCtrl'>
  <div my-child dirclick='childEvent'>

  </div>
  <div my-child dirclick='childEvent'>

  </div>
</div>

Your parentCtrl is like this:

.controller('parentCtrl',function($scope){
  $scope.childEvent = function(){
    //some code
  }
})

So your directive should be like this:

.directive('myChild',function(){
  return {
    template : "<button ng-click='clickme()'>clickme</button>",
    scope : {clickme : '=dirclick'},
    restrict : 'A',

(I have not written full code for directive so wait for it)

Now whatever written in dirclick attribute of your child directive will be binded to parentCtrl's object named childEvent. And it will be binded to clickme of your directive. Now you can call parentCtrl's childEvent() function from your child directive's clickme() fn. (I am so bad at explaining, better see the code below)

You would love to do any broadcast now. So declare you childEvent() fn of parentCtrl like this:

$scope.childEvent = function(){
  $scope.$broadcast('child event',{say:"hello"});
}

And define your child directive's controller like this:

controller : function($scope){
    $scope.$on('child event',function(event,data){
    alert(data.say);
  });
}

This might help you solving your problem.

Please find related fiddle : https://jsfiddle.net/Lo7ehrdn/1/

Suggestion - don't play much with $broadcast as it goes down from top to all your child scopes. If you draw a tree where your root is the parent scope, then broadcast will run down to all the last leaves.

Hope this helps.

Upvotes: 1

Related Questions