Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling order of link function in nested and repeated angularjs directives

I'm fairly new to Javascript programming and I have only touched upon AngularJS. In order to evaluate it I decided to write a simple note application. The model is really simple, a list of notes where each note has a label, a text and a list of tags. However I ran into problem passing data between isolated scopes of nested directives.

I have three directives, notes, note and tagger (defining new elements with the same names). Each of them using an isolated scope.

The notes directive uses ng-repeat to "render" each one of its notes with the note element.

The note directive uses the tagger element to "render" the list of tags.

The note directive defines scope: { getNote: "&", ... } in order to pass a note instance from the list of notes to the note controller/directive. The getNote(index) function is called in the link function of the note directive. This works fine!

The tagger directive defines scope: { getTags: "&", ... } in order to pass a list of tags for a given note to the tagger controller/directive. The getTags function is called in the link function of the tagger directive. This does not work!

As I understand it, the problem is that the link functions of the directives are called in an inconsistent order. Debugging the application shows that the link functions are called in the following order:

  1. link function in the notes directive (adding the getNote function to the notes scope)

  2. link function in the tagger directive of the first note (calling getTags in the parent note scope) function

  3. link function in the first note directive (adding the getTags to the scope) (calling getNote in the parent notes scope)

  4. link function in the tagger directive of the second note (calling getTags in the parent note scope) function

  5. link function in the second note directive (adding the getTags to the scope) (calling getNote in the parent notes scope)

This will not work since in #2 the scope of the first note has not yet an getTags function.

A simplistic example can be found in Plunker.

Hence, my question boils down to: What determines the order in which link functions are called in nested directives.

(I solved to the problem using $watch on getTags in the tagger directive...)

regards

like image 681
positively4th Avatar asked Aug 18 '13 00:08

positively4th


People also ask

What is Link function in AngularJS directive?

link function is basically used to manipulate the DOM( Document Object Model ) element using custom directive. link option in custom directive registers DOM listener and also update the DOM. Watch the live demo or download code from the link given below. Download script.

What is attrs in AngularJS?

Using attrs you are able to access the attributes defined in your html tag like <fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"> So in this case you will have access to the symbol and readonly attributes.


1 Answers

Quoting Josh D. Miller who had kindly responded to a similar question I had :

" Just a couple of technical notes. Assume that you have this markup:

<div directive1>
  <div directive2>
    <!-- ... -->
  </div>
</div>

Now AngularJS will create the directives by running directive functions in a certain order:

directive1: compile

directive2: compile

directive1: controller

directive1: pre-link

directive2: controller

directive2: pre-link

directive2: post-link

directive1: post-link

By default a straight "link" function is a post-link, so your outer directive1's link function will not run until after the inner directive2's link function has ran. That's why we say that it's only safe to do DOM manipulation in the post-link. "

like image 98
Taye Avatar answered Oct 05 '22 20:10

Taye