Xavier_Ex
Xavier_Ex

Reputation: 8810

Isolated scope cannot access variables higher in the scope chain

Before anyone marks this as a duplicate, I had found similar questions on SO:

  1. Isolate scope variable is undefined
  2. unable to access rootscope var in directive scope

But mine in particular is a different question by itself.

I have a directive with isolated scope. In its post link function I'm trying to access a variable that happens to be in the root (top most) scope. In my isolated scope I have tried myVar: '@' and myVar: '=' but none of them worked, the myVar is undefined in the directive scope. Below is the return statement of my directive:

{
    restrict: 'E',
    replace: true,
    transclude: true,
    template: tmpl,

    scope: {
        myVar: '@'
    },

    link: {
        post: function ($scope) {
            // $scope.myVar is undefined
            // $scope.$root.myVar is defined
        }
    }
}

In my console I logged the current scope object and I can trace the $parent all the way up to the root and see the var is in there, so the var is also accessible through the $root of the current scope.

My question is then why doesn't the '@' and '=' work in this case? Is it because the var is defined higher up in the chain other than the immediate parent, or because possibly some parent scope in the middle is itself an isolated scope and breaks the chain of reference to that var?

Upvotes: 0

Views: 254

Answers (1)

lucuma
lucuma

Reputation: 18339

If you have an isolated scope, you are going to want to pass to your directive whatever it is you want it to use for my-val. As a simple example let's say we have this in our html:

 <my-test my-var='{{test}}'></my-test>

Our main controller is going to have a scope variable named test.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.test = 'World';
});

So, if you notice the directive is setting my-var = {{test}}.

Now our directive's scope variable of myVar will be bound to that value.

app.directive('myTest', function()  {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    template: '<span>{{myVar}}</span>',

    scope: {
        myVar: '@'
    },

    link: {
        post: function (scope) {
            console.log(scope.myVar);
        }
    }
  }
});

Here is a simple demo: http://plnkr.co/edit/rkbLJ0dJk4OrtyOD3c8w?p=preview

Upvotes: 2

Related Questions