Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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?

share|improve this question
    
That 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? – Mark Rajcok May 14 '13 at 15:11
1  
@MarkRajcok It has an isolate scope. – Pedr May 14 '13 at 15:32
up vote 149 down vote accepted

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()
        }
    };
});

fiddle

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).

share|improve this answer
    
I'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. – Pedr May 14 '13 at 17:40
    
@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. – Mark Rajcok May 14 '13 at 17:54
    
No 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? – Pedr May 14 '13 at 17:58
    
@Pedr, sure, go right ahead. – Mark Rajcok May 14 '13 at 19:19
1  
@FredrikL, for multiple directives on the same element, please see stackoverflow.com/a/28735005/215945 – Mark Rajcok May 5 '15 at 21:21

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>
share|improve this answer

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 : "=",
        ....
    },
share|improve this answer

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);
        }
    };
});
share|improve this answer

protected by Pankaj Parkar Jun 11 '15 at 19:02

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.