0
votes

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?

1
How are you assigning myVar in the html template? (BTW, @ assigns the variable to the value of a DOM attribute, that's never going to evaluate to some $scope value). - rvignacio

1 Answers

2
votes

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