0

Even after reading this http://docs.angularjs.org/guide/compiler I don't understand the compilation process that AngularJS uses. I don't understand the difference between the two of them, nor when they are invoked.

Could someone try to explain it somehow a little easier?

3 Answers 3

1

Maybe it will help to identify how they are related:

compile():

  • gives you access to the element before it has been inserted into the DOM. (performance advantage)

  • returns a link() function.

  • if you specify your own compile function, you can alternatively return an object with pre and post properties and define your pre-link and post-link functions, as described below.

link():

  • There are actually two "linking" functions, pre and post.

  • pre is called after your element has scope, but before actually linking to the document and calling post, angular will recursively compile any child elements. When your element's post link function has been called, all children directives have been compiled and linked. So you'd use pre if you needed to make any changes to the scope before children are compiled and inserted.

  • post is the function returned from compile() by default and occurs after the element has been inserted into the DOM and the proper scope object has been initialized. At this point, any child directives have been compiled and inserted into your element.

other notes:

  • when you specify a link() parameter in the directive options:

    return { replace: ..., scope: ..., link: function(){...}, };

    that function is returned by compile() ( unless you also specify a compile() function, in which case, the link property is ignored ), so if you use the link option, you are saying, "I only need to do stuff after the element has been added to the document and the scope is ready to use."

  • The same is true when you return a function instead of an options object in your directive; that function is your link() function.

When angular is connecting your directive to your document (when it sees your directive attribute or element in your HTML) it will call the compile() function for the instance it is creating. compile() returns a link() function or an object with pre and post link functions. So say there is a portion of my HTML like so:

<div my-directive class='first'>
  <div my-directive class='second'>
  </div>
</div>

Let's assume you are assigning your own compile function:

angular.module('myapp').directive('myDirective', function(){
  return {
    replace: true,
    compile: function(){
      console.log("i'm compile");
      return {
        pre:  function(){ console.log("i'm pre-link"); },
        post: function(){ console.log("i'm post-link"); }
      };
    }
  }
});

when you're app runs you'll see (I added comments for clarity):

"i'm compile"    // class = first
"i'm pre-link"   // class = first
"i'm compile"    // class = second
"i'm pre-link"   // class = second
"i'm post-link"  // class = second
"i'm post-link"  // class = first
Sign up to request clarification or add additional context in comments.

9 Comments

So they are something like callbacks in the compilation cycle? So how often are the functions invoked? Is the compile function invoked once while link is called X number of times for some event? The question is basically: when and how often are they called?
good question. They are both called once for each element that uses that directive. When angular is connecting your directive to your document (when it sees your directive attribute or element in you HTML) it will call the compile() function for the instance it is creating. compile() returns a link() function or an object with pre and post link functions. after your directive element has been inserted into the document, those are called (in the order explained in my answer). Does that help? For experimentation, you could put print statements in those functions.
To be honest I don't know if I became wiser. The thing is, in the documentation they states that separating the compile and link phase they managed to increase the performance since the had a template. I thought compile was invoked once, the link for each time.
The reason there is a performance increase is because, when compile is called, the element has not been added to the document, so you can do things to it that don't effect the DOM. Does that make sense? I also added more explanation to my answer.
Ah, so that is the reason. So both compile and link is invoked for each item element with a certain directive as in ng-repeat?
|
0

compilation is the process of walking the DOM and applying directives to nodes (inserting templates etc.), whereas linking is the process of "connecting" the compiled DOM with a certain scope, so all of your bindings in the compiled DOM will operate on that scope.

Comments

0

I haven't thoroughly understood that concept either, but I'll try to answer the question.

The compile function is a chance that you have to manipulate the dom. For example, the ng-repeat directive has got a compile function which runs the loop and creates all the for example. Note that at this point the DOM element has not linked to any scope. The compile function will return a function that you can the use to link the scope to the DOM elements. From what i understood, if you provide a compile function then you don't need to have a link function. The reason is that the compile function will return a link function.

On the other hand, the link function is where the scope will be linked with the given DOM element. Here you have the chance to register any watched you want, register event listeners etc.

This increases the performance of applying directives.

3 Comments

What is the function that the compile function returns? Is it the DOM element?
No it's no the DOM element. It's a function with the following 'signature' function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }. Alternatively, it can return an object. Refer to this docs for more details docs.angularjs.org/api/ng/service/$compile
@LuckyLuke it is the link function. see my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.