How do I pass multiple attributes into an Angular.js attribute directive?
Solution 1
The directive can access any attribute that is defined on the same element, even if the directive itself is not the element.
Template:
<div example-directive example-number="99" example-function="exampleCallback()"></div>
Directive:
app.directive('exampleDirective ', function () {
return {
restrict: 'A', // 'A' is the default, so you could remove this line
scope: {
callback : '&exampleFunction',
},
link: function (scope, element, attrs) {
var num = scope.$eval(attrs.exampleNumber);
console.log('number=',num);
scope.callback(); // calls exampleCallback()
}
};
});
If the value of attribute example-number
will be hard-coded, I suggest using $eval
once, and storing the value. Variable num
will have the correct type (a number).
Solution 2
You do it exactly the same way as you would with an element directive. You will have them in the attrs object, my sample has them two-way binding via the isolate scope but that's not required. If you're using an isolated scope you can access the attributes with scope.$eval(attrs.sample)
or simply scope.sample, but they may not be defined at linking depending on your situation.
app.directive('sample', function () {
return {
restrict: 'A',
scope: {
'sample' : '=',
'another' : '='
},
link: function (scope, element, attrs) {
console.log(attrs);
scope.$watch('sample', function (newVal) {
console.log('sample', newVal);
});
scope.$watch('another', function (newVal) {
console.log('another', newVal);
});
}
};
});
used as:
<input type="text" ng-model="name" placeholder="Enter a name here">
<input type="text" ng-model="something" placeholder="Enter something here">
<div sample="name" another="something"></div>
Solution 3
You could pass an object as attribute and read it into the directive like this:
<div my-directive="{id:123,name:'teo',salary:1000,color:red}"></div>
app.directive('myDirective', function () {
return {
link: function (scope, element, attrs) {
//convert the attributes to object and get its properties
var attributes = scope.$eval(attrs.myDirective);
console.log('id:'+attributes.id);
console.log('id:'+attributes.name);
}
};
});
Solution 4
This worked for me and I think is more HTML5 compliant. You should change your html to use 'data-' prefix
<div data-example-directive data-number="99"></div>
And within the directive read the variable's value:
scope: {
number : "=",
....
},
Related videos on Youtube
Undistraction
Updated on March 17, 2020Comments
-
Undistraction over 4 years
I have an attribute directive restricted as follows:
restrict: "A"
I need to pass in two attributes; a number and a function/callback, accessing them within the directive using the
attrs
object.If the directive was an element directive, restricted with
"E"
I could to this:<example-directive example-number="99" example-function="exampleCallback()">
However, for reasons I won't go into I need the directive to be an attribute directive.
How do I pass multiple attributes into an attribute directive?
-
Mark Rajcok about 11 yearsThat depends on the type of scope your directive creates (if any). Choices are: no new scope (default, or explicit with
scope: false
), new scope (with normal prototypal inheritance, i.e.,scope: true
), and isolate scope (i.e.,scope: { ... }
). What type of scope does your directive create? -
Undistraction about 11 years@MarkRajcok It has an isolate scope.
-
-
Undistraction about 11 yearsI've edited the example HTML to use snake-case. I know I can't use it as an element. That's the point of the question.
-
Mark Rajcok about 11 years@Pedr, yeah, sorry I read too fast about the element usage. I updated the answer, noting that you also need to use snake-case for the attributes too.
-
Undistraction about 11 yearsNo problem. Thanks for your answer. I've edited the attribute names to use snake-case. You OK if I remove that from your answer as it was just a silly error by me and distracts from the point of the actual question and answer?
-
blaster almost 11 yearsI don't get this - how does the directive know to name the exact same thing specified in the directive usage ("exampleCallback()") in its scope? ("callback : '&exampleCallback') Shouldn't the scope be "callback : "&exampleFunction" ?
-
Mark Rajcok almost 11 years@blaster, yes thanks for the correction. I updated the answer.
-
Fredrik L about 9 yearsDoes this work even if there are multiple directives on the same element?
-
Mark Rajcok about 9 years@FredrikL, for multiple directives on the same element, please see stackoverflow.com/a/28735005/215945
-
James Drinkard over 7 yearsI had this same requirement, except I had to pass in a string array of values. This code gave me the starting point to get it working! Thanks Mark!
-
Somnium over 7 yearsHow can I get
exampleNumber
in controller (updated value, not that which was at the time of creating directive) without defining it in scope parameters? -
Peter Boomsma over 4 yearsIs it possible to send a boolean value using a object? I tried
{{true}}
but it still returns the string valuetrue
.