Suppose I have two attribute directive called myFoo
and myBar
. These directives are defined with restrict: 'A'
.
Then I have an element
<div my-foo my-bar></div>
In what order would the compiling/linking functions be called? Does my-foo
's compile always be called before my-bar
's compile ?
Directives are compiled in priority order, from highest to lowest. The default is 0. If set to true then the current priority will be the last set of directives which will execute (any directives at the current priority will still execute as the order of execution on same priority is undefined).
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.
As with components, you can add multiple directive property bindings to a host element.
Compiler is an AngularJS service which traverses the DOM looking for attributes. The compilation process happens in two phases. Compile: traverse the DOM and collect all of the directives. The result is a linking function. Link: combine the directives with a scope and produce a live view.
In addition to @valepu's answer here is the description for the priority
property for the DDO (Directive Definition Object):
TL;DR The default priority
is 0
and if you wish to change the order in which elements get compiled you'd have to increase the priority
for the element(s).
When there are multiple directives defined on a single DOM element, sometimes it is necessary to specify the order in which the directives are applied. The priority is used to sort the directives before their compile functions get called. Priority is defined as a number. Directives with greater numerical priority are compiled first. Pre-link functions are also run in priority order, but post-link functions are run in reverse order. The order of directives with the same priority is undefined. The default priority is 0.
In your case, if you do not specify the priority
for your directives, my-bar
will be compiled first followed by my-foo
. However, notice that the controller gets initialized first, then the pre
followed by the post
link function. Also, the order is important here: Angular compiles the directives alternating. The follownig is my console.log
printing which shows the process:
bar controller
foo controller
pre bar
pre foo
post foo
post bar
If you wish to play around, I have set up a Plunker.
Now, if you change the priority
to priority: 1
you will get the following output:
foo controller
bar controller
pre foo
pre bar
post bar
post foo
As you can see, it starts with myFoo
and goes on to myBar
. So myFoo
now has a higher priority.
Update 1
Question:
How do you deal with a sititation, in which two different vendor directives (A and B) depend on each other and the order of execution is important? Is it possible without changing the vedor's settings?
I would suggest to implement a decorator as follows:
app.config(function($provide) {
$provide.decorator('myFooDirective', function($delegate) {
var directive = $delegate[0];
directive.priority = 9;
return $delegate;
});
});
Usually, a decorator intercepts the creation of a service, allowing it to override or modify the behaviour of a service. However, you could also decorate your directive as shown above. In the decorator you could set the priority to your needs to effect the order of execution. As far as I know the priority
property is the only way to control the order in which the directives get applied. When using a decorator you modify / override the priority
property but not directly its settings in case you don't mean the DDO.
The Plunker above is also updated with the decorator implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With