Does Angular Create New Dom Tree After Compile Phase Or Continue Working With Original Modified Dom?
Solution 1:
I've spent 3 hours investigating Angular's source code (it's written in so hard to read manner) and found the answer to my question. Angular doesn't distinguish between template and instance elements inside, it works with the same tree it has when it begins compiling. Here is the essence of the source code that demonstrates that:
var element = $("body");
compile(element)($rootScope);
functioncompile(DOMElementsTree) {
var compositeLinkFn = compileNodes(DOMElementsTree);
returnfunctionpublicLinkFn(scope) {
var$linkNode = DOMElementsTree;
compositeLinkFn(scope, $linkNode);
return$linkNode;
}
}
functioncompileNodes(nodesList) {
var linkFns = [];
nodesList.forEach(function (node) {
var nodeLinkFn = applyDirectivesToNode(node);
var childNodes = nodesList.childNodes;
var childLinkFn = !!childNodes.length ? compileNodes(childNodes) : null;
if (nodeLinkFn || childLinkFn) {
linkFns.push(i, nodeLinkFn, childLinkFn);
}
});
returnfunctioncompositeLinkFn(scope, nodeList) {
linkFns.forEach(function (linkFn) {
var nodeLinkFn = linkFn[1];
var childNodeLinkFn = linkFn[2];
if (nodeLinkFn) {
nodeLinkFn(childLinkFn, scope, nodeList);
} elseif (childNodeLinkFn) {
childLinkFn(scope, nodeList)
}
});
}
}
functionapplyDirectivesToNode() {
// this is where compile functions of all directives on a node are executed
}
functionnodeLinkFn() {
// here pre link and post link functions are executed
}
functionchildLinkFn() {
// here pre link and post link functions are executed
}
You can see that applyDirectivesToNode
which executes compile
functions of a directive doesn't return any new DOM node, instead it modifies DOMElementsTree
that it receives by references and compositeLinkFn
continues working with this DOM instance.
Initially I had this piece of sample code in my question taking from here:
var$compile = ...; // injected into your codevar scope = ...;
varparent = ...; // DOM element where the compiled template can be appendedvar html = '<div ng-bind="exp"></div>';
// Step 1: parse HTML into DOM elementvar template = angular.element(html);
// Step 2: compile the templatevar linkFn = $compile(template);
// Step 3: link the compiled template with the scope.var element = linkFn(scope);
// Step 4: Append to DOM (optional)parent.appendChild(element);
So in this extract the last step deals with the result of the publicLinkFn
function, namely $linkNode
in my code above.
Solution 2:
The DOM
element is indeed created during step1, however it is only available in the browser memory but not reflected in the actual page DOM.
Since the element has been created from Javascript (var html = ...
) once it is compiled and linked, you need to put it back to the page using append
so the user can actually see and interact with it.
Update I don't understand what you are asking exactly, but I don't think you will find an answer on StackOverflow. What you need is a forum or more lecture about the internal functionning of AngularJS. I highly recommend you to read this article: http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives/
Update2 From my understanding (and accoding to the article cited above), Angular will first compile the template from dir-parent
and then compile its children using that same template. If you have modified this template during the top compile phase, for instance by removing dir-child1
, then indeed there is nothing else to compile and Angular will then proceed with the pre-link
and finally post-link
.
Post a Comment for "Does Angular Create New Dom Tree After Compile Phase Or Continue Working With Original Modified Dom?"