Building Advanced Directives
If an element contains multiple directives then for that element:
- A scope is created, if necessary
- Each directive's directive controller is instantiated
- Each directive's pre-link function is called
- Any child elements are linked
- Each directive's post-link function is called
This means that when a directive controller is instantiated the directive's element
and its children have not yet been fully linked. But when the link functions (pre
or post) are called, all the directive controllers for that element have already been
instantiated. This is why directive controllers can be passed to link functions.
The post-link function is called after the compiler has completely
finished compiling and linking the current element and all its child
elements. This means that any changes to the DOM at this stage
will not be noticed by the AngularJS compiler.
This is useful when you want to wire up third party libraries to
elements, such as a JQuery plug-in, which may modify the DOM in
a way that would confuse the AngularJS compiler.
Accessing other controllers
Link functions receive a fourth parameter that contains any directive controllers
that have been required by the directive. We saw how this enabled us to access
ngModelController in Chapter 9, Building Advanced Directives.
myModule.directive('validateEquals', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ngModelCtrl) {
...
};
});
Here the validateEquals directive is requiring the ngModel directive controller,
which is then passed to the link function as ngModelCtrl.
In contrast, a directive controller cannot have other directive controllers injected
into it.