例如,我有以下 HTML:
<div dir-parent>
<div dir-child1></div>
</div>
编译阶段指令 dirParent
将接收内部包含 div
的模板 DOM 元素与 dirChild1
指示。如果我不改变这个html
里面dirParent
的编译函数,然后调用 dirChild1
的编译函数指示。但是,如果我删除 <div dir-child1="" some-child1-attr></div>
里面dirParent
的编译函数,然后 Angular 继续处理这个修改后的 DOM,该 DOM 不再具有 dir-child1
的 div指令和 dir-child1
的编译函数指令永远不会被执行。
我假设一旦 Angular 完成执行编译函数,它就会从 html
构建新的 DOM 在编译函数期间修改。这个假设正确吗?这个修改 DOM 似乎被称为实例 DOM 元素,并且在 pre-link
期间可用。阶段,所以我假设这是 Angular 构造实例元素 DOM 树的阶段。
最佳答案
我花了 3 个小时研究 Angular 的源代码(它的编写方式很难阅读)并找到了我的问题的答案。 Angular 不区分内部的模板元素和实例元素,它在开始编译时使用相同的树。下面是源代码的本质,它演示了:
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
}
您可以看到,执行指令的 compile
函数的 applyDirectivesToNode
不会返回任何新的 DOM 节点,而是修改了 DOMElementsTree
它通过引用接收,并且 compositeLinkFn
继续使用此 DOM 实例。
最初,我在提问 from here 中有这段示例代码:
var $compile = ...; // injected into your code
var scope = ...;
var parent = ...; // DOM element where the compiled template can be appended
var html = '<div ng-bind="exp"></div>';
// Step 1: parse HTML into DOM element
var template = angular.element(html);
// Step 2: compile the template
var 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);
因此,在此摘录中,最后一步处理 publicLinkFn
函数的结果,即上面代码中的 $linkNode
。
关于javascript - Angular 在编译阶段后会创建新的 DOM 树还是继续使用原始修改后的 DOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29437692/