Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I evaluate attribute values in a directive?

Is there a good way to have AngularJS directives evaluate an attribute passed in as a parameter?

Here's a simplified example to show my problem (I recognize you could implement this behavior without a directive):

link: function postLink(scope, element, attrs) {    
      debugger; // scope.$parent already knows the value of teacher here
      scope.sendEmail = function(){
          alert(attrs.recipient);
          //window.open("mailto:" + attrs.recipient);
      }
    }

I would like the directive to use the value of teacher.email (note that the link function has the correct value for scope.$parent.teacher) instead of the string teacher.email.

like image 926
Daniel Avatar asked Mar 19 '13 18:03

Daniel


People also ask

What are attribute directive in angular?

Angular attribute directives are a number of built-in directives that we can add to our HTML elements that give them a dynamic behavior. In summary, an attribute directive changes the appearance or behavior of a DOM element.

How do you access the directive variable in a controller?

You just create a myVar variable in your controller and pass it to the directive using my-var attribute. Since you are using two way binding, any changes made to myVar by the directive are available in your controller.

What is directive element?

What are Directives? At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ( $compile ) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.


1 Answers

As @Ajay already mentioned in a comment, you can use scope.recipient. This works because you created an isolate scope in your directive:

scope: {    
   recipient: "="
},

This creates a directive scope property named recipient which is two-way databound to a parent scope property. Which parent property? The one defined by your attribute: recipient="teacher.email" – hence parent scope property teacher.email is bound to isolate scope property recipient.

If your directive will not be altering the value of recipient, you should probably use '@' instead of '='. '@' gives us "one-way strings":

scope: {    
   recipient: "@"
},

You'll need to alter your HTML though:

<sendemail recipient="{{teacher.email}}"></sendemail>

In the sendEmail() function, we can still use scope.recipient, just like we did for '='.


If we use scope: true instead, the directive will create a "normal" child scope, rather than an isolate scope. In the directive we would then use

scope.$eval(attrs.recipient)

to obtain the value. This works because of the way JavaScript prototypal inheritance works. $eval will look for property teacher.email and not find it on the directive child scope. It then follows the prototype chain to the parent scope and finds it there.

like image 53
Mark Rajcok Avatar answered Sep 28 '22 08:09

Mark Rajcok