Directive compilation in angularjs
Manipulating DOM
If we have worked on templates in other JavaScript framework/library like Backbone
and jQuery
, they process the template as a string and result as a string. We have to inject this result string into the DOM
using innerHTML()
or some other way, because there is no two way binding that needs to happen, we render the markup once, and do it again when any changes are there. But it is not the case in AngularJS.
The AngularJS way
AngularJS
processes the template in entirely different way. It works directly on HTML DOM
fragments(in memory) rather than strings and manipulates it as required. It uses two-way data-binding between model and view to sync our data.
Note that Angular processes on DOM nodes instead of strings contents.
There are basically two phases in which Angular does this, compile
and link
.
The concept of compile
and link
comes from C
language, where you first compile the code and then link it to actually execute it. The process is very much similar in AngularJS
as well.
The Process
1. Compile – $compile
function traverse the DOM
and collect all directives from DOM. For each directive it finds, it adds it to a list of directives. Once the entire DOM has been traversed, it will sort that list of directives by their priority. It takes our HTML markup or template one by one and returns a link
function.
[js]
var $compile = …; // injecte $comple into our code to get link function
var scope = …; // scope for new directive
var parent = …; // DOM element where we want to apply our directive
var html = ‘<div ng-show="data"></div>’; // Our HTML code
var template = angular.element(html); // Step 1A: parse HTML into DOM element to pass in $compile to get link function
var linkFn = $compile(template); // Step 1B: compile the template and return link function
[/js]
2. Link – The above link function (Returned by $compile
function) combines the directives with a scope to give as two way data binding. Any data-related changes affecting the model are immediately propagated to the matching view(s), and any changes made in the view(s) are reflected in the underlying model.
[code lang=”javascript”]
var element = linkFn(scope); // Step 2A: link ‘scope’ with the compiled template (Two way binding).
parent.appendChild(element); // Step 2B: Inject our element to parent DOM element
[/code]
This can help in scenarios where you get some Markup as a string, and want it to use it with AngularJS
, you’ll need to compile the HTML to make it work.
Hope this will help you to understand the compilation process in AngularJS.