15
votes

What is the order of execution of directive functions? The documentation doesn't seem to address this.

Ex

  1. template / templateUrl (is evaluated)
  2. controllerFn
  3. compileFn
  4. linkFn

Answer

From answer below: http://plnkr.co/edit/79iyKSbfxgkzk2Pivuak (plunker shows nested and sibling directives)

  1. Template is parsed
  2. compile() (changes made to the template within compile are proliferated down to linking functions)
  3. controller()
  4. preLink()
  5. postLink()
2
Compile, controller, link. I don't know about templates. See also github.com/angular/angular.js/wiki/Understanding-Directives - Mark Rajcok
@MarkRajcok, thanks! I need to know about all 4 though. - Jakob Jingleheimer
@jacob - Here is a demonstration on the execution order of compileFn, controllerFn, preLinkFn, and postLinkFn. Are you referring to template compilation when you say template evaluation? - tamakisquare
@tamakisquare, yes I mean template compilation (when the template is available). - Jakob Jingleheimer
@jacob - Available as in the final rendered view? If so, it doesn't happen until linkFn/postLinkFn is done, because linkFn/postLinkFn is where DOM manipulation and transformation happen. - tamakisquare

2 Answers

4
votes

Pre-linking function: Executed before the child elements are linked. Not safe to do DOM transformation since the compiler linking function will fail to locate the correct elements for linking.

Post-linking function: Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function.

Above excerpt is taken from the official docs on directives.

So, to answer your question, Post-linking/Link function is when/where you can safely operate on element.children().

9
votes

on related note, here my understanding of exec order across the DOM.

Here is a demo (open browser JS console)

Given this DOM using directive foo:

  <div id="1" foo>
    one
    <div id="1_1" foo>one.one</div>
  </div>

  <div id="2" foo>two</div>

...AngularJS will traverse the DOM - twice - in depth-first order:

1st pass foo.compile()

1) compile: 1

2) compile: 1_1

3) compile: 2

2nd pass: foo.controller() traversing down; foo.link() while backtracking

controller: 1

controller: 1_1

link: 1_1

link: 1

controller: 2

link: 2