Not able to access angular directive's isolated scope

47 views Asked by At

First Directive:

app.directive("myDirectiveOne", function($rootScope){
    return {
        templateUrl : "/custom-one-html.html",
        restrict: "AE", 
        replace:true,
        scope: {
            somedata: "=",
            flags: "=",
            functionone: "&"
        }
        ,controller: function($rootScope,$scope, $element) {
           $scope.firstFunction = function(){
                console.log("First function is getting called")
           }
$scope.$on('firstBroadcast',function(event, data){
                $rootScope.$broadcast('secondBroadcast', data)
            });

    }

Second Directive:

app.directive("myDirectiveTwo", function($rootScope){
    return {
        templateUrl : "/custom-two-html.html",
        restrict: "AE", 
        replace:true,
        scope: {
            data: "=",
            functiontwo: "&"
        }
        ,controller: function($rootScope,$scope, $element) {
           $scope.secondFunction = function(){
                console.log("Second function is getting called")
                $rootScope.$broadcast('firstBroadcast', {})
           }
$scope.$on('secondBroadcast',function(event, data){
                $scope.callSomeFunctionWithData(data);
            });
$scope.secondFunction();

    $scope.editFunction = function(x){
console.log("This is the edit function", x);
        }

Parent Controller:

$scope.parentFuntion = function(){
        console.log("No trouble in calling this function")
}

So, the problem is when I try calling a function from a myDirectiveTwo html template, the controller which is active is the parent controller and not the isolated one.

May be it has something to do with the broadcasts I am using?

Html Code:

<div ng-repeat="x in data">
    <h5>{{x.name}}</h5>
    <button ng-click="editFunction(x)">Edit</button>
</div>

The strange thing is I get data values and ng-repeat works fine on load. But, when I click on the button it doesnt do anything. And if I add the same function in the parent controller, it gets called.. :( How do I make the isolated scope controller active again..?

2

There are 2 answers

3
Protozoid On

The problem is that ng-repeat creates a child scope, therefore the editFunction ends up being on the parent scope.

From docs

... Each template instance gets its own scope, where the given loop variable is set to the current collection item ...

Docs here

You can verify that this is the issue by getting your button element's scope and checking the $parent, as such angular.element(document.getElementsByTagName("button")).scope()

Although considered code smell, you can append $parent to your function call in order to access it, though keep in mind this now places a dependency on your HTML structure.

<button ng-click="$parent.editFunction(x)">Edit</button>

0
User-8017771 On

The issue was that I was using a deprecated method replace:true. This caused the unexpected scenarios.. As @Protozoid suggested, I looked at his link and found the issue.. To quote from the official documentation:

When the replace template has a directive at the root node that uses transclude: element, e.g. ngIf or ngRepeat, the DOM structure or scope inheritance can be incorrect. See the following issues: Incorrect scope on replaced element: #9837 Different DOM between template and templateUrl: #10612

I removed replace:true and its fine now :)

This is the link: Here