Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - inner directive - Order of postLink function calls change when I am replacing template property with templateUrl property

I have a weird situation. If I have an outer directive that contains 2 directives

inner-directive1 - has a template defined.

inner-directive2 - has a templateUrl defined.

The inner-directive1 postLink function is being called before the outer-directive postLink function - as expected.

But, the inner-directive2 poslink function is being called after the outer-directive postLink - NOT as expected.

The calls to the postLink function are : inner-directive1, outer-directive, inner-directive2 and I was expecting : inner-directive1, inner-directive2, outer-directive.

The template for the outer directive is:

<div ng-transclude><div inner1></div><div inner2></div></div>

please look at the JsFiddle

Does anyone know the reason why? And is there a way I can make it work as it is expected ?

JSFiddle - Please look at the console log. Thanks, Ben

like image 766
Ben Laniado Avatar asked Oct 19 '13 20:10

Ben Laniado


2 Answers

Here's why, from the Angular directive docs(http://docs.angularjs.org/guide/directive):

templateUrl - Same as template but the template is loaded from the specified URL. Because the template loading is asynchronous, the compilation/linking is suspended until the template is loaded.

So that particular directive stops linking until your template is loaded. During that time your other directives jump in and run.

If the timing of you link function is critical, you'll need to include the template directly instead of as a templateUrl. Unless someone can come up with a cool way around this.

like image 111
KayakDave Avatar answered Oct 29 '22 19:10

KayakDave


Not sure of the exact use-case, but I ran into this issue when trying to use element[0].querySelector('#dynamicId');

This would result in "null" in this case since the link function was being executed from input 1 after outer link.

The fix was rather simple, in the outer directive's link function, wrap the code using element.ready():

element.ready(function(){
     var item = element[0].querySelector('#dynamicId');
     item.bind('blur', function(){
         alert('blur')
     });
})

This allows me to find the dynamic element and attach any events even if it's being async loaded from the template url.

like image 36
Donald White Avatar answered Oct 29 '22 20:10

Donald White