AngularJS Directive Template vs TemplateUrl (synchronous vs asynchronous)

As one would hope the output of the template  and templateUrl is the same, its just that one has to be careful about when the controllers and link function are available.  Run this example JSFiddle and see.

template -synchronous lifecycle: Angular uses a depth first approach for DOM compilation and the compiler instantiates the each controller until the DOM is traversed. Then the link function of deepest directive is instantiated and angular traverses the DOM in reverse order instantiating each link function.

templateUrl -asynchronous lifecycle: Angular uses a depth first approach for DOM compilation and the compiler instantiates the first controller but then assumes an asynchronous response from the templateUrl and immediately instantiates the first directive’s Link function. The DOM is traversed where the compiler instantiates each directive’s controller and than it’s link function.
The example shown in JSFiddle  defines three directives using template option.  Each template loads in another directive. The output shows the order the compiler instantiates the controllers from the parent to the child  in a descending order and then instantiates the Link functions from the youngest child back to the parent.

Directive A Controller
Directive B Controller
Directive C Controller
Directive C LinkFn
Directive B LinkFn
Directive A LinkFn

The code then defines three directives using the templateUrl option to load the directives.  The output shows where each directive’s controller and link function are instantiated which is only in descending order.

Directive A URL Controller
Directive A URL LinkFn
Directive B URL Controller
Directive B URL LinkFn
Directive C URL Controller
Directive C URL LinkFn

Final thoughts

Angular best practices recommends using templateUrl and since angular will store the html in templateCache it makes sense to preload the html using something like grunt JavaScrip / HTML2JS. The design of the directives should assume:

  • Expect child directives to be complied at some unknown point in the future
  • When the template does arrive understand the scope could be very different
  • Do not assume variable bindings exist in the DOM at the time the controller or link Fn are executed.

If the templates are preloaded, all the child directive’s will be available by the end of the digest cycle.