About manual
This manual will be useful to a developer, who is already familiar with the basis of AngularJS framework and already knows how to create own directives, knows what a directive identification object is and its features, which are described in detail in the official documentation.
In this manual we’ll fully consider directives life cycle, sort out in more details the functions of a directive identification object (link, compile, controller), identify the order of their implementation and bring special features of their using.
Let’s get started!
While creating a directive to control its behavior, you can use any of the following directive identification object properties: compile, link, controller. In them, we can manipulate markup, work with child elements, implement business logic, attach event handlers and assign observers and watches to attributes.
Compile is a function, that transforms DOM template to the angular application. Not all the directives transform the template, therefore it is often not used.
Link is a function, that is responsible for registering DOM event handlers and for DOM updating. Most often, the major part of the directive logic is here.
Controller is a function of constructor of directive controller.
Compile and Link functions will return either the object with preLink and postLink functions or just return the function, which will be postLink.
- preLink – runs before directive child elements are processed and bound.
- postLink – runs after directive child elements are processed and bound.
Which feature and for what purposes is the most suitable we’ll analyze a bit further, but now we’ll consider in details the order of their implementation and the directive life cycle.
Implementation order
At first, we’ll consider implementation order of controller, compile, preLink and postLink functions when the directive is initialized.
For one directive
We’ll consider an example of log directive, which makes output to the console of the transferred string at different stages of its load.
HTML markup:
JS directive declaration code:
Console output will be the following:
some-div (compile)
some-div (controller)
some-div (pre-link)
some-div (post-link)
In this example we see that at first compile runs, then controller, next preLink, and the last postLink.
For included directives
HTML markup has tree-like structure and therefore elements that contain directives can often have child elements, each with its own directive. To understand the order they are processed in, we slightly modify the HTML template of the previous example and consider the output in the console.
HTML markup:
The console output will look like that:
// The compile phase
parent (compile)
..first-child (compile)
..second-child (compile)
// The link phase
parent (controller)
parent (pre-link)
..first-child (controller)
..first-child (pre-link)
..first-child (post-link)
..second-child (controller)
..second-child (pre-link)
..second-child (post-link)
parent (post-link)
Here we can see that load of included directives starts after preLink function of the parent directive and its postLink function will be called only after the full loading cycle of all child directives.
Main phases
In the previous example, two main loading phases of the directive are clearly visible: compile phase and link phase. Let’s look at them in more detail.
Compilation
After load of HTML markup by a browser, AngularJS calls its $compile function, which also runs along the markup from top to the bottom and calls the compile function of all detected directives. The result of this function is link function, which will be called in the phase.
The following graph shows this process:
Linking
In this phase, AngularJS first links the controller function, which will create directive controller. Then preLink function will be called, after that directives, found in child elements, will be processed and after that postLink function is called.
If html elements are added dynamically, for example with the help of ng-repeat directive, they will also go through all the compilation and linking phases.
Link phase graph:
Full graph of the compilation and linking phases
In this graph, you can see at what moment the source content of the directive element is removed (Transcluded content removed) and stored in memory for future insertion into the directive template or for access to the controller.
It is also shown at what stage the directive gets HTML template and at what moment AngularJS creates visible area (scope and isolate scope) for the directive.
Functions usage
Next we’ll consider basic functions of directive identification object separately and determine for what purposes which one is more suitable, and which implementation is not recommended.
Compilation functions
This is a place for implementation of (source) manipulations with templates, which aren’t bound yet with visible area or with data linking.
Recommended to:
- Manipulate the markup to serve as template for copies (clones).
Not recommended to:
- Attach event handler
- Work with child elements
- Assign observers by attributes
- Assign watches at visible area
Controller function
The basic meaning of the controller function:
- Defines controller business logic (methods).
- Defines variables visible area
Not recommended to:
- Work with child elements (they may not be displayed yet and not attached to visible area)
Pre-link function
Pre-link function is rarely used, but it can be useful in special scenarios.
For example, when child controller registers itself with parent controller.
Immediately after calling this function, the wiring phase will start for child elements, for which the current visible area will serve as the parent one.
Not recommended to:
- Work with child elements
Post-link function
When post-link function is called, all the previous steps have completed – template preparation, data linking etc. If the directive doesn’t contain business logic and doesn’t require preliminary template processing, you can immediately use the function of directive identification object link. In contracted notation, it will be post-link function.
Recommended to:
- Manipulate DOM elements
- Attach event handlers
- Work with child elements
- Assign observers by attributes
- Watches configuration at visible area
Comparative table of directive functions
For convenience, we will make all recommendations on the use of directive functions in a separate table.
Conclusion
Clear knowledge of AngularJS directive life cycle will allow developing more complex components of an application, to implement good engineering solutions to complex problems, and it will prevent the occurrence of common errors.
Good luck and prosperity to everyone!