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.
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
The three types of directives in Angular are attribute directives, structural directives, and components.
Components are directives with templates. The only difference between Components and the other two types of directives is the Template. Attribute and Structural Directives don't have Templates.
The Angular Directive can be classified into two types: structural and attribute directives. Structural directives alter layout by adding, removing, and replacing elements in DOM.
If we also specify an input property in our directive's class using the same value as the selector property value we can input data into our directive using the attribute on the host element. This instructs Angular that the appBtnGrow class member property is now an input that can receive a value from the host element.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With