我认为,一旦完成了angular函数的编译功能,它就会在编译函数期间根据 html modified 构建新的DOM.这个假设正确吗?经过修改的 DOM似乎被称为 instance DOM元素,并且在 pre-link 阶段可用,因此我认为这是角构造实例元素DOM树.解决方案我花了3个小时研究Angular的源代码(它以难以阅读的方式编写),并找到了我问题的答案.Angular不区分内部的模板元素和实例元素,它与开始编译时使用的树相同.这是演示该代码的源代码的精髓: var元素= $("body");compile(element)($ rootScope);函数compile(DOMElementsTree){var CompositeLinkFn = compileNodes(DOMElementsTree);返回函数publicLinkFn(scope){var $ linkNode = DOMElementsTree;CompositeLinkFn(scope,$ linkNode);返回$ linkNode;}}函数compileNodes(nodesList){var linkFns = [];NodesList.forEach(function(node){var nodeLinkFn = applyDirectivesToNode(node);var childNodes = nodesList.childNodes;var childLinkFn = !! childNodes.length?compileNodes(childNodes):null;如果(nodeLinkFn || childLinkFn){linkFns.push(i,nodeLinkFn,childLinkFn);}});返回函数CompositeLinkFn(scope,nodeList){linkFns.forEach(function(linkFn){var nodeLinkFn = linkFn [1];var childNodeLinkFn = linkFn [2];如果(nodeLinkFn){nodeLinkFn(childLinkFn,作用域,nodeList);} else if(childNodeLinkFn){childLinkFn(作用域,nodeList)}});}}函数applyDirectivesToNode(){//这是执行节点上所有指令的编译功能的地方}函数nodeLinkFn(){//在此执行前链接和后链接功能}函数childLinkFn(){//在此执行前链接和后链接功能} 您可以看到执行指令的 compile 函数的 applyDirectivesToNode 不会返回任何新的DOM节点,而是会修改 DOMElementsTree 它通过引用接收,并且 compositeLinkFn 继续使用此DOM实例.最初,我的问题中包含这段示例代码,从这里获取: var $ compile = ...;//注入您的代码var scope = ...;var parent = ...;//可以在其中附加编译后的模板的DOM元素var html ='< div ng-bind ="exp"></div>';//步骤1:将HTML解析为DOM元素var template = angular.element(html);//步骤2:编译模板var linkFn = $ compile(template);//步骤3:将已编译的模板与作用域链接.var element = linkFn(scope);//步骤4:附加到DOM(可选)parent.appendChild(element); 因此,在此摘录中,最后一步处理的是 publicLinkFn 函数的结果,即我上面的代码中的 $ linkNode .For example, I have the following HTML:<div dir-parent> <div dir-child1></div></div>During compilation phase directive dirParent will receive template DOM element that has inside of it the div with a dirChild1 directive. If I don't change this html inside dirParent's compile function, then compile function is then called for dirChild1 directive. However, if I remove <div dir-child1="" some-child1-attr></div> inside dirParent's compile function, then angular continues processing this modified DOM that no longer has a div with dir-child1 directive and so compile function for dir-child1 directive is never executed.I assumed that once angular is done executing compile functions it builds new DOM from html modified during compile functions. Is this assumption correct? This modified DOM seems to be referred as instance DOM elements and is available during pre-link phase, so I assume that this is the phase when angular constructs instance elements DOM tree. 解决方案 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);function compile(DOMElementsTree) { var compositeLinkFn = compileNodes(DOMElementsTree); return function publicLinkFn(scope) { var $linkNode = DOMElementsTree; compositeLinkFn(scope, $linkNode); return $linkNode; }}function compileNodes(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); } }); return function compositeLinkFn(scope, nodeList) { linkFns.forEach(function (linkFn) { var nodeLinkFn = linkFn[1]; var childNodeLinkFn = linkFn[2]; if (nodeLinkFn) { nodeLinkFn(childLinkFn, scope, nodeList); } else if (childNodeLinkFn) { childLinkFn(scope, nodeList) } }); }}function applyDirectivesToNode() { // this is where compile functions of all directives on a node are executed}function nodeLinkFn() { // here pre link and post link functions are executed}function childLinkFn() { // 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 = ...;var parent = ...; // 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. 这篇关于角在编译阶段后会创建新的DOM树还是继续使用原始修改的DOM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-30 08:53