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