[Analysis of compile and link function in]ng directive
September 2014
Usually everyone in the use of the ng
instructions, the most of the link function is the link
attribute, the following article will tell you, complie
pre-link
post-link
The usage and the difference.
Original address
angularjs
The instructions are magical, allowing you to create very semantic and highly reusable components that can be understood as web components
pioneers.
There are many articles about how to use the instructions on the Internet and related books, compared with each other, there are few compile
link
differences, let alone pre-link
with post-link
.
Most of the tutorials are simple to compile
ng
use internally, and suggest that you use attributes only, and most of the instructions are in link
this case.
This is very unfortunate, because the correct understanding of the differences in these functions will improve your ng
understanding of the internal operating mechanism and help you develop better custom directives.
So come along with me to see what these functions are and when they should be used in the next step.
- This article assumes that you have a certain understanding of the instructions, and if not, it is strongly recommended that you take a look at this article Angularjs Developer Guide sections on Directives
How is the instruction handled in NG?
Before starting the analysis, let's take a look at ng
how the instructions are handled.
When a browser renders a page, it essentially reads the html
identity, then establishes dom
the node and dom
broadcasts an event to us when the tree is created.
When you load the application code with a label in the page script
ng
, ng
listen for the above dom
completion event and find ng-app
the element with the attribute.
When such an element is found, it begins with the beginning of the ng
dom
element, so if it ng-app
is added to the html
element, it is ng
processed from the html
element dom
.
Starting from this starting point, ng
recursively finds all the child elements inside, conforming to the rules of instruction defined in the application.
ng
How to handle a directive is actually dependent on the object's properties when it is defined, and you can define either a compile
function or a function link
pre-link
post-link
instead link
.
So what are the differences between these functions? Why use it? And when to use it?
Take these questions and follow me through the puzzle.
A section of code
To explain the differences between these functions, I'll use a simple and easy-to-understand example
- If you have any questions, please don't hesitate to add your comments below.
Look at the following section of the html
tag code
<level-one> <level-two> <level-three> Hello </level-three> </level-two> </level-one>
Then a piece of js
code
VarApp=Angular.Module(' Plunker ',[]);functionCreatedirective(Name){Returnfunction(){Return{Restrict:E,Compile:function(TElem,Tattrs){Console.Log(Name+': Compile ');Return{Or::function(Scope,Ielem,Iattrs){Console.Log(Name+': Pre link ');},Post:function(Scope,Ielem,Iattrs){Console.Log(Name+': Post link ');}}} } } } app.directive ( ' levelone ' Createdirective ( ' levelone ' app. Directive ( ' leveltwo ' createdirective ( ' leveltwo ' app. Directive ( ' levelthree ' createdirective ( ' levelthree '
The result is very simple: let ng
's handle three nested instructions, and each instruction has its own, complile
pre-link
post-link
function, and each function prints a line of things in the console to identify itself.
This example gives us a simple idea of the ng
internal process when processing instructions.
Code output
The following is a result of the output from the console
If you want to try this example yourself, click this plnkr and then view the results in the console.
Analyze code
The first one to note is the order in which these functions are called:
// COMPILE PHASE // levelOne: compile function is called // levelTwo: compile function is called // levelThree: compile function is called // PRE-LINK PHASE // levelOne: pre link function is called // levelTwo: pre link function is called // levelThree: pre link function is called // POST-LINK PHASE (Notice the reverse order) // levelThree: post link function is called // levelTwo: post link function is called // levelOne: post link function is called
This example clearly shows ng
link
that all the instructions were compiled before and then link
divided into pre-link
post-link
phases.
Note that the compile
pre-link
order of execution is executed sequentially, but just the post-link
opposite.
So the above has clearly identified the different stages, but compile
pre-link
what is the difference between the same execution order, why is it divided into two different functions?
Dom
To dig deeper, let's simply modify the code above, which also prints the variables in the argument list in each function. element
VarApp=Angular.Module(' Plunker ',[]);functionCreatedirective(Name){Returnfunction(){Return{Restrict:E,Compile:function(TElem,Tattrs){Console.Log(Name+': Compile = '+TElem.Html());Return{Pre:function(Scope,Ielem,Iattrs){Console.Log(Name+': Pre link = '+Ielem.Html());},Post:function(Scope,Ielem,Iattrs){Console.Log(Name+': Post link = '+Ielem.Html());}}}}}} app. Directive(' Levelone ', createdirective(' Levelone ')); app. Directive(' leveltwo ', createdirective(' leveltwo ')); app. Directive(' Levelthree ', createdirective(' Levelthree '));
Note that the output of the console.log
output in addition to the original html
markup basically no other change.
This should be able to deepen our understanding of these function contexts.
Run the code again to see
Output
The following is a result of the output from the console
If you want to run the results yourself, you can click on this plnkr and check the output in the console.
Observation
dom
The result of the output can reveal something interesting: the content is different from the dom
compile
pre-link
two functions
So what's going on? Compile
We already know ng
that dom
processing begins when the build is complete dom
.
So when ng
it comes to traversing, dom
it touches the level-one
element, and from its definition there is a need to perform some necessary functions.
Because the compile
function is defined in the directive level-one
object of the instruction, it is called and passed an element
object as its argument
If you look closely, you'll see that when the browser creates the element
object, it's still the most primitive html
tag.
- In
ng
, the original is dom
usually used to identify template element
, so I compile
use the name when defining the function parameters tElem
, this variable points to template element
.
Once the levelone
function in the instruction is run compile
, ng
it iterates through its nodes recursively dom
, and then level-two
level-three
repeats those operations with the above.
Post-link
pre-link
before we dive into the function, let's look at the post-link
function.
- If you only use a function when defining an instruction, you will treat the
link
ng
function post-link
as a handler, so we'll discuss the function first.
When ng
all of the dom
functions have been traversed and run out compile
, the associated function is called backwards post-link
.
dom
Now start the reverse and execute the post-link
function, so the previous reverse call looks a little strange, in fact it makes sense.
When you run a directive that contains sub-directives post-link
, the reverse post-link
rule guarantees that its sub-directives post-link
are already running.
So, when we run the function of the level-one
instruction post-link
, we can guarantee that level-two
level-three
the and actually have post-link
already run.
That's why people think it's the safest post-link
or the default place to write business logic.
But why is it element
compile
different here?
Once the function of the ng
instruction is called, compile
an instance object is created and an object is template element
provided for it, which may be a element
scope
scope
new instance, or it may already exist, may be a child scope
, or it may be independent scope
, these have to rely on the attribute values in the directive definition object scope
So when linking
this happens, the instance element
and the scope
object are already available, and are ng
passed as arguments to post-link
the function's argument list.
- I personally always use
iElem
the name to define a link
function's arguments, and it is a pointer to element
the instance
So post-link
pre-link
The Parameter object of the () function element
is an element
instance instead of one template element
.
So the output in the above example is different.
Pre-Link
When you write a post-link
function, you can guarantee that the function post-link
of all its child instructions is executed when the function post-link
is executed.
In most cases, it can be done better, so usually we will use it to write instruction code.
However, it ng
provides us with an additional hook
mechanism, which is the pre-link
function, which guarantees that the functions of all child instructions are executed post-link
. Run some other code.
This sentence is worth repeated deliberation.
pre-link
The function is guaranteed to be element
executed on the instance and before all of its child instructions are post-link
run.
So it makes it post-link
quite meaningful to reverse the execution of the function, which is itself the original sequential execution pre-link
function
This also means that the pre-link
function runs before the function of all its child instructions pre-link
, so the complete reason is:
The function of an element pre-link
is guaranteed to be executed before all of its child instructions are run post-link
and pre-link
run. See
Review
If we look back at the original output, we can clearly identify what happened:
Here the ELEMENTS is still the ORIGINAL TEMPLATE ELEMENTSCOMPILE PHASELevelone:compile function is called on original DOM//leveltwo:compile function is called on original DOM //levelthree:compile fun Ction is called in original DOM //as of Here, the ELEMENTS has BEEN instantiated and / /Is BOUND to A SCOPE //(e.g. Ng-repeat would has multiple INSTANCES) //pre-link PHA SE //levelone:pre link function is called on element instance //leveltwo:pre link Fu Nction is called on element instance //levelthree:pre link function was called on element instance //post-link PHASE (Notice the reverse order) //levelthree:post LINK function is called on Element instance //leveltwo:post link function is called on element instance //Levelo Ne:post link function is called on element instance span>
Profile
Looking back at the above analysis, we can describe the differences and usage of these functions:
Compile function
Use the compile
function to change the dom
original ( template element
) ng
before creating the original dom
instance and creating the scope
instance.
Can be applied when multiple instances need to be generated, element
only one template element
case, ng-repeat
is one of the best examples, it is in the compile
function phase to change the original dom
generation of multiple original dom
nodes, and then each generates an element
instance. because compile
runs only once, so you can improve performance when you need to build multiple element
instances.
template element
And the associated properties are passed to the function as arguments compile
, but scope
this is not possible at this time:
Here's what the function looks like
/** * Compile function * * @param tElem - template element * @param tAttrs - attributes of the template element */ function(tElem, tAttrs){ // ... };
Pre-Link function
A function pre-link
can be used to run some business code ng
after the function is executed compile
, but before the function of all its child instructions post-link
will be executed.
scope
Objects and element
instances will be passed as arguments to the pre-link
function:
Here's what the function looks like
/** * Pre-link function * * @param scope - scope associated with this istance * @param iElem - instance element * @param iAttrs - attributes of the instance element */ function(scope, iElem, iAttrs){ // ... };
Post-link function
Use a post-link
function to execute the business logic, at which point it already knows that all its child instructions have been compiled and that the pre-link
post-link
function has been completed.
This is why it is considered the safest and the default code for writing business logic.
scope
Instances and element
instances are passed as arguments to the post-link
function:
Here's what the function looks like
/** * Post-link function * * @param scope - scope associated with this istance * @param iElem - instance element * @param iAttrs - attributes of the instance element */ function(scope, iElem, iAttrs){ // ... };
Summarize
Now you should compile
have a pre-link
clear understanding of the post-link
difference between this function.
If not, and you are a serious ng
developer, then I strongly suggest you read this article again until you know it.
Understanding these concepts is important to help you understand ng
how the native commands work and to help you optimize your own custom directives.
If you have any questions, please add your questions in the comments below.
You will then analyze the other two questions about the directive:
Finally, if you find anything wrong with this article, please send me a comment in time
Thank you!
The difference between Angularjs compine and link