Evan Levesque
Evan Levesque

Reputation: 3213

Access scope from a scope-isolated directive

I am trying to call a scope function from inside a scope isolated directive, here is my code :

angular.module('directive', [])
.directive('dirz', function() {
  return {
    restrict:'E',
    link: function(scope, elm, attrs, ctrl) {
    },
    controller: function() {
    }    
  };
})
.directive('dir1', function() {
  return {
    require: 'dirz', 
    scope:{},
    link: function(scope, elm, attrs, ctrl) {  
    }
  };
}) 
.directive('dir2', function() {
  return {
    restrict:'E',
    link: function(scope, elm, attrs, ctrl) {
      // this function is never called bacause of isolated scope ?
      scope.click = function(){
        console.log("somebody clicked me!!");
      }
    }
  }; 
});

and my html

<dirz dir1>
  <!-- I want to call click scope function in dir2 -->
  <button ng-click="click()">click</button>
</dirz>

<dir2></dir2>

this is a plunk

Am I doing it right, or is this an angular antipattern ?

Upvotes: 0

Views: 55

Answers (1)

Michael Kang
Michael Kang

Reputation: 52867

The click() handler is not accessible within dir1's isolated scope.

To trigger both clicks, move the button HTML to your directive's template (the template will be linked against the isolated scope) and then call $broadcast to send a message to dir2. This might be your best option since the DIVs are siblings to eachother rather than in a parent/child relationship.

.directive('dir1', function() {
  return {
    require: 'dirz', 
    template: '<button ng-click="click()">click</button>',
    controller: function($scope, $rootScope) { 
         $scope.click = function() {
             console.log('somebody clicked me');
             $rootScope.$broadcast('click');
         }
    },
    scope:{},
    link: function(scope, elm, attrs, ctrl) {  
    }
  };
}) 
.directive('dir2', function() {
  return {
    restrict:'E',
    link: function(scope, elm, attrs, ctrl) {
      // this function is never called bacause of isolated scope ?
      scope.$on('click', function() {
           console.log('received click message');
      });
    }
  }; 
});

HTML

<dirz dir1>
</dirz>

<dir2>
</dir2>

Upvotes: 1

Related Questions