When the AngularJS HTML compiler encounters a directive, it runs the directive’s compile function, which returns the link()
function. The link()
function is added to the list of AngularJS directives. After all directives have been compiled, the HTML compiler calls the link()
functions in order, based on priority.
If you want to modify the DOM inside a custom directive, you should use a link()
function. The link()
function accepts the scope
, element
, attributes
, controller
, and transclude
function associated with the directive, enabling you to manipulate the DOM directly within the directive. The transclude function is a handle that is bound to the transclusion scope.
Inside the link()
function, you handle the $destroy
event on the directive element and clean up anything necessary. The link()
function is also responsible for registering DOM listeners to handle browser events.
The link()
function uses the following syntax:
link: function(scope, element, attributes, [controller], [transclude])
The scope
parameter is the scope of the directive, element
is the element where the directive will be inserted, attributes
lists the attributes declared on the element, and controller
is the controller specified by the require
option. The transclude
parameter is a handle to the transclude function.
The transclude function provides access to the element created when the transclusion of the contents of the original element occurs. If you just want a transcluded element with the inherited scope, you can just call the transclude function. For example:
link: function link(scope, elem, attr, controller, transcludeFn){
var transcludedElement = transcludeFn();
}
You can also access the clone of the transcluded element by specifying a clone
parameter. For example:
link: function link(scope, elem, attr, controller, transcludeFn){
transcludeFn(function(clone){
//access clone here . . .
});
}
You can also access the clone of the transcluded element with a different scope by applying a scope
parameter as well as the clone
parameter. For example:
link: function link(scope, elem, attr, controller, transcludeFn){
transcludeFn(scope, function(clone){
//access clone here . . .
});
}
The following directive shows the implementation of a basic link()
function that sets a scope variable, appends data to the DOM element, implements a $destroy
event handler, and adds a $watch
to the scope:
directive('myDirective', function() {
return {
scope: {title: '='},
require: '^otherDirective',
link: function link(scope, elem, attr, controller, transclude){
scope.title = "new";
elem.append("Linked");
elem.on('$destroy', function() {
//cleanup code
});
scope.$watch('title', function(newVal){
//watch code
});
}
};
The link
property can also be set to an object that includes pre and post properties that specify prelink and postlink functions. In the preceding example where link is set to a function, the function is executed as a postlink function, meaning that it is executed after the child elements are already linked, whereas the prelinked function is executed before the child elements are linked. Therefore, you should do DOM manipulation only in the postlink function. In fact, it is quite rare to need to include the prelink function.
The following shows an example of the syntax for including both the prelink and the postlink functions:
directive('myDirective', function() {
return {
link: {
pre: function preLink(scope, elem, attr, controller){
//prelink code
},
post: function postLink(scope, elem, attr, controller){
//postlink code
},
}
};