Compile :
This is the phase where Angular actually compiles your directive. This compile function is called just once for each references to the given directive. For example, say you are using the ng-repeat directive. ng-repeat will have to look up the element it is attached to, extract the html fragment that it is attached to and create a template function.If you have used HandleBars, underscore templates or equivalent, its like compiling their templates to extract out a template function. To this template function you pass data and the return value of that function is the html with the data in the right places.The compilation phase is that step in Angular which returns the template function. This template function in angular is called the linking function.
Linking phase :
The linking phase is where you attach the data ( $scope ) to the linking function and it should return you the linked html. Since the directive also specifies where this html goes or what it changes, it is already good to go. This is the function where you want to make changes to the linked html, i.e the html that already has the data attached to it. In angular if you write code in the linking function its generally the post-link function (by default). It is kind of a callback that gets called after the linking function has linked the data with the template.
Controller :
The controller is a place where you put in some directive specific logic. This logic can go into the linking function as well, but then you would have to put that logic on the scope to make it “shareable”. The problem with that is that you would then be corrupting the scope with your directives stuff which is not really something that is expected. So what is the alternative if two Directives want to talk to each other / co-operate with each other? Ofcourse you could put all that logic into a service and then make both these directives depend on that service but that just brings in one more dependency. The alternative is to provide a Controller for this scope ( usually isolate scope ? ) and then this controller is injected into another directive when that directive “requires” the other one. See tabs and panes on the first page of angularjs.org for an example.
Controller function
Each directive’s controller
function is called whenever a new related element is instantiated.
Officially, the controller
function is where one:
- Defines controller logic (methods) that may be shared between controllers.
- Initiates scope variables.
Again, it is important to remember that if the directive involves an isolated scope, any properties within it that inherit from the parent scope are not yet available.
Do:
- Define controller logic
- Initiate scope variables
Do not:
- Inspect child elements (they may not be rendered yet, bound to scope, etc.)
Compile function
Each directive’s compile
function is only called once, when Angular bootstraps.
Officially, this is the place to perform (source) template manipulations that do not involve scope or data binding.
Primarily, this is done for optimisation purposes; consider the following markup:
<tr ng-repeat="raw in raws">
<my-raw></my-raw>
</tr>
The <my-raw>
directive will render a particular set of DOM markup. So we can either:
- Allow
ng-repeat
to duplicate the source template (<my-raw>
), and then modify the markup of each instance template (outside thecompile
function). - Modify the source template to involve the desired markup (in the
compile
function), and then allowng-repeat
to duplicate it.
If there are 1000 items in the raws
collection, the latter option may be faster than the former one.
Do:
- Manipulate markup so it serves as a template to instances (clones).
Do not
- Attach event handlers.
- Inspect child elements.
- Set up observations on attributes.
- Set up watches on the scope.
Pre-link function
Each directive’s pre-link
function is called whenever a new related element is instantiated.
As seen previously in the compilation order section, pre-link
functions are called parent-then-child, whereas post-link
functions are called child-then-parent
.
The pre-link
function is rarely used, but can be useful in special scenarios; for example, when a child controller registers itself with the parent controller, but the registration has to be in a parent-then-child
fashion (ngModelController
does things this way).
Do not:
- Inspect child elements (they may not be rendered yet, bound to scope, etc.).
Post-link function
When the post-link
function is called, all previous steps have taken place – binding, transclusion, etc.
This is typically a place to further manipulate the rendered DOM.
Do:
- Manipulate DOM (rendered, and thus instantiated) elements.
- Attach event handlers.
- Inspect child elements.
- Set up observations on attributes.
- Set up watches on the scope.