Search code examples
javascriptangularjsangularjs-directiveangular-broadcast

AngularJS: Broadcast event from parent only to it children


I want to broadcast event from parent directive to child. But if I use scope.broadcast in parent directive link function, then all children in every "parent" directive receive it.

How it works now: If parent (1) broadcast event, then child (1.1) and (2.1) receive event.

How I want it to work: I want to broadcast event from parent (1) only to child (1.1), not child (2.1).

My directive checked if element is on screen. I want only one directive like that and only this directive should send event to others.

<div>
    <div parent> <!-- 1 -->
        <div child></div> <!-- 1.1 -->
    </div>

    <div parent> <!-- 2-->
        <div child></div> <!-- 2.1 -->
    </div>
</div>

Solution

  • Probable reason - parent directive shares the same scope, that's why your event is propagated to all child directives.

    Solution - each directive should define its own scope, which prototypically inherits from parent. ($root <-- parent <-- child)

    <!DOCTYPE html>
    <html ng-app="app">
    
      <head>
        <script data-require="[email protected]" data-semver="1.4.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script>
          angular
            .module('app', [])
            .directive('parent', function() {
              return {
                scope: true,
                link: function(scope, element) {
                  element.on('click', function() {
                    scope.$broadcast('parent-event');
                  });
                }
              };
            })
            .directive('child', function() {
              return {
                scope: true,
                link: function(scope) {
                  scope.$on('parent-event', function() {
                    console.log('child(' + scope.$id + ') caught parent event');
                  });
                }
              };
            });
        </script>
      </head>
    
      <body>
        <div>
          <div parent> Parent {{ $id }}
              <div child>Child {{ $id }}</div>
          </div>
    
          <hr />
    
          <div parent> Parent {{ $id }}
              <div child>Child {{ $id }}</div>
          </div>
      </div>
      </body>
    </html>
    

    Plunker