AngularJS follows a two-phase process to convert HTML templates into a fully functional UI:
- Compilation Phase (Template Parsing & Processing)
- Linking Phase (Binding Data & Event Handlers)
This process enables AngularJS to dynamically extend HTML with directives (ng-model
, ng-repeat
, etc.) and ensure two-way data binding.
Step 1: Compilation Phase
In this phase, AngularJS parses the HTML and looks for directives, expressions, and bindings.
How It Works?
- AngularJS loads the raw HTML template.
- It traverses the DOM and finds Angular directives (
ng-model
,ng-repeat
, etc.). - Directive functions (compile functions) are executed, allowing directives to modify the DOM.
Example: AngularJS Template
<div ng-app="myApp" ng-controller="MainController">
<p>Hello, {{ name }}!</p>
<input type="text" ng-model="name">
</div>
AngularJS Compilation Process:
- Finds
ng-app
→ Initializes AngularJS. - Finds
ng-controller
→ AttachesMainController
. - Finds
{{ name }}
→ Marks it for two-way binding. - Finds
ng-model="name"
→ Links input to$scope.name
.
At this point, AngularJS does not bind data yet—it just prepares the DOM.
Step 2: Linking Phase
After compilation, AngularJS links the template with the scope.
How It Works?
- The Linking function connects the compiled template with the
$scope
object. - It creates watchers (
$scope.$watch
) to track changes in the model. - Event listeners (like
ng-click
) are registered to handle user interactions.
Controller Example (Linking Stage)
var app = angular.module("myApp", []);
app.controller("MainController", function ($scope) {
$scope.name = "John Doe"; // Initial data binding
});
Binding Mechanism
$scope.name
initializes as"John Doe"
.- The
{{ name }}
expression updates when$scope.name
changes. - If the user types into the
<input>
,ng-model="name"
updates$scope.name
, triggering a digest cycle to refresh the UI.
Compilation vs Linking Summary
Phase | What Happens? | When? |
---|---|---|
Compilation | Angular scans the DOM, finds directives, and prepares the template. | When AngularJS initializes. |
Linking | AngularJS binds data to the template and adds event listeners. | When the controller loads. |
Deep Dive: Custom Directives (Compile & Link Functions)
AngularJS allows you to define custom directives, giving control over the compilation and linking phases.
Example: Custom Directive with Compile & Link Functions
app.directive("customDirective", function () {
return {
restrict: "E",
template: "<p>Hello, {{ username }}</p>",
compile: function (element, attributes) {
console.log("Compiling...");
return {
pre: function (scope, element, attrs) {
console.log("Pre-linking...");
},
post: function (scope, element, attrs) {
console.log("Post-linking...");
}
};
}
};
});
Explanation:
- Compile function runs once when AngularJS processes the directive.
- Pre-link function executes before scope bindings are initialized.
- Post-link function executes after scope bindings, ensuring two-way data binding.
Common Issues in Compilation & Linking
1️⃣ Direct DOM Manipulation in Controllers
Bad Practice:
app.controller("MainController", function ($scope) {
document.getElementById("myDiv").innerHTML = "Hello!";
});
Solution: Use directives for DOM changes:
app.directive("updateText", function () {
return function (scope, element) {
element.text("Hello!");
};
});
2️⃣ Infinite Digest Cycles
Bad Code (Modifying Scope Inside Watcher):
$scope.$watch("name", function (newVal, oldVal) {
$scope.name = newVal + "!";
}); // Causes infinite loop
Solution: Avoid Changing the Watched Variable
$scope.$watch("name", function (newVal, oldVal) {
console.log("Name changed:", newVal);
});
Key Takeaways
AngularJS compiles templates first, then links them to the scope.
Directives have both compile and linking phases.
Avoid DOM manipulations inside controllers; use directives instead.
Use $watch
carefully to prevent infinite digest cycles.