Nesting directives within directives

angularjs, angularjs-directive

Solution

Interpolated attributes (i.e., attributes that use {{}}s) and isolate scope properties defined with '@' are not available when the link function runs. You need to use `attrs.$observe()` (or `scope.$watch( @ property here, ...)`) to get the values (asynchronously).

So, `scope.bindValue` is not available when you are trying to use it.

Similarly, in your subDirective, attribute `value` has {{}}s, so its value will also not be available when you are trying to use it. You also need to define an '@' directive property for this.

Working fiddle.

The reason for the asynchronous requirement is that the items inside the {{}}s may change, and you normally want your directive to notice (and then do something -- like update the "addOne" values). '@' is normally used with isolate scopes when the attribute value contains {{}}s.

If attribute values are constants, and you're not going to use the values in a template (or templateUrl), then '@' probably shouldn't be used. In the link function, just use `attrs.attrName` if the value is a string, or `scope.$eval(attrs.attrName)` if the attribute is a number or boolean (or `parseInt(attrs.attrName)` if you know it is a number).

Problem

Regarding AngularJS directives I've ran into a situation where I'm calling a directive from within another directive and I have the following questions. - Why can't I referecne scope.bindValue in my link function? Is there a way I can compute a value from scope.bindValue and set it to scope? - Why can the subdirective bind using "@" in scope:{} but not use scope.value = attrs.value in the link function? All of the below can be seen at http://jsfiddle.net/sdg9/AjDtt/13/ HTML: ``` <directive bind-value="12" value="7"></directive> ``` JS: ``` var myApp = angular.module('myApp', []); var commonTemplate = '<div>{{name}} bind-value is: {{bindValue}} </div><div>{{name}} value is: {{value}} </div><div>{{name}} add one to bind-value is: {{addOneBindValue}} </div><div>{{name}} add one to value is: {{addOneValue}} </div><br/>'; myApp.directive('directive', function () { return { scope: { bindValue: "@", }, template: commonTemplate + '<br/><sub-directive bind-value="{{value}}" value="{{value}}"></sub-directive>', restrict: 'E', link: function (scope, element, attrs) { scope.name = "Directive"; scope.value = attrs.value; scope.addOneBindValue = parseInt(scope.bindValue) + 1; scope.addOneValue = parseInt(scope.value) + 1; } }; }); myApp.directive('subDirective', function () { return { scope: { bindValue: "@" }, template: commonTemplate, restrict: 'E', link: function (scope, element, attrs) { scope.name = "SubDirective"; scope.value = attrs.value; scope.addOneBindValue = parseInt(scope.bindValue) + 1; scope.addOneValue = parseInt(scope.value) + 1; } }; }); ``` Output: ``` Directive bind-value is: 12 Directive value is: 7 Directive add one to bind-value is: null <--- why? Directive add one to value is: 8 SubDirective bind-value is: 7 SubDirective value is: <--- why? SubDirective add one to bind-value is: null SubDirective add one to value is: null ```

Original source