Conflicting directive priority issue

Loading

If you’re experiencing conflicting directive priority issues, it means multiple directives are competing to control the same DOM element, and AngularJS doesn’t know which one to apply first.


1️⃣ What is Directive Priority?

In AngularJS, each directive has a priority (default is 0). Higher priority directives execute before lower ones.

app.directive("highPriority", function() {
return {
restrict: "A",
priority: 100, // Higher priority
link: function() {
console.log("High-priority directive executed");
}
};
});

app.directive("lowPriority", function() {
return {
restrict: "A",
priority: 10, // Lower priority
link: function() {
console.log("Low-priority directive executed");
}
};
});
<div high-priority low-priority></div>

Output in Console:

High-priority directive executed
Low-priority directive executed

The highPriority directive runs first because it has a priority of 100.


2️⃣ Common Causes & Fixes

Cause 1: Multiple Directives on the Same Element Without Defined Priorities

If multiple directives exist on an element without explicit priorities, Angular applies them in an undefined order, potentially causing unexpected behavior.

Problematic Code

app.directive("firstDirective", function() {
return {
restrict: "A",
link: function() {
console.log("First directive executed");
}
};
});

app.directive("secondDirective", function() {
return {
restrict: "A",
link: function() {
console.log("Second directive executed");
}
};
});
<div first-directive second-directive></div>

🛠 Output (Unpredictable Execution Order):

First directive executed
Second directive executed

OR

Second directive executed
First directive executed

Problem: The execution order is not controlled.

Solution: Define Directive Priority

app.directive("firstDirective", function() {
return {
restrict: "A",
priority: 200, // ✅ Higher priority
link: function() {
console.log("First directive executed");
}
};
});

app.directive("secondDirective", function() {
return {
restrict: "A",
priority: 100, // Lower priority
link: function() {
console.log("Second directive executed");
}
};
});

Now, execution order is controlled:

First directive executed
Second directive executed

First directive runs first because of higher priority (200 vs. 100).


Cause 2: Multiple Directives with ng-model and ng-bind

Some built-in AngularJS directives also have priorities.
For example, ng-model (priority: 1) conflicts with ng-bind (priority: 0).

Problematic Code

<input type="text" ng-model="name" ng-bind="name">

Problem: ng-bind updates the DOM, but ng-model controls the data. Since ng-bind has lower priority, it gets overridden.

Solution: Remove ng-bind and use {{name}} instead

<input type="text" ng-model="name">
<p>{{ name }}</p>

Now, ng-model updates correctly.


Cause 3: Using ng-repeat with ng-if

ng-repeat (priority 1000) conflicts with ng-if (priority 0).
If ng-if is inside ng-repeat, the list might not render correctly.

Problematic Code

<ul>
<li ng-repeat="item in items" ng-if="item.show">{{ item.name }}</li>
</ul>

Problem: ng-if is executed after ng-repeat, causing unexpected DOM behavior.

Solution: Use ng-show Instead

<ul>
<li ng-repeat="item in items" ng-show="item.show">{{ item.name }}</li>
</ul>

Since ng-show only hides elements (instead of removing them), this prevents conflicts.


Cause 4: Directives with terminal: true Preventing Others from Executing

When a directive has terminal: true, it stops further directive execution.

Problematic Code

app.directive("stopDirective", function() {
return {
restrict: "A",
priority: 500,
terminal: true, // ❌ Prevents lower-priority directives from executing
link: function() {
console.log("stopDirective executed");
}
};
});

app.directive("anotherDirective", function() {
return {
restrict: "A",
priority: 100,
link: function() {
console.log("anotherDirective executed");
}
};
});
<div stop-directive another-directive></div>

Output:

stopDirective executed

Problem: anotherDirective never executes because stopDirective has terminal: true.

Solution: Remove terminal: true unless absolutely necessary

terminal: false;  //  Allow execution of lower-priority directives

3️⃣ Best Practices for Managing Directive Priorities

Always define priority if multiple directives exist on the same element.
Higher priority (priority: 1000) executes first.
Use terminal: true carefully, as it blocks lower-priority directives.
Check built-in directive priorities (ng-repeat, ng-model, ng-if).
Use ng-show instead of ng-if inside ng-repeat.


Final Thoughts

  • Directive priorities matter when multiple directives modify the same element.
  • Setting explicit priority values prevents execution order conflicts.
  • Avoid using terminal: true unless necessary.
  • Use alternative directives (ng-show instead of ng-if) when needed.

Leave a Reply

Your email address will not be published. Required fields are marked *