我正在编写一些Angular指令,根据传递的某些属性更改其模板。它们在结构上看起来像这样:
app.directive('mydir', function ($compile) {
return {
restrict: 'E',
replace: true,
transclude: true,
compile: function (elem, attrs, transclude) {
var replacement;
// operations
return function (scope, lElem, lAttrs) {
transclude(scope, function (clone, scope) {
// more operations
});
elem.replaceWith($compile(replacement)(scope)); // IMPORTANT
};
}
};
});
并且在this Plunkr。现在,正如所写的(好的,充实的),如果你试图嵌套它们,这些指令不起作用。内部指令以其完全擦除的转换元素结束。但是,如果我用elem.replaceWith(...)
替换lElem.replaceWith(...)
(在Plunkr中的Javascript文件的第36行),一切都很好,我可以根据需要嵌套多次。为什么会这样?这有什么区别?我知道elem
未编译而且lElem
是,但这实际意味着什么以及它如何影响我的代码?此外,不鼓励在link
函数中进行DOM操作吗?
我尝试了什么。我自己试图对此进行调试,看起来内部指令的编译函数被调用了两次(我假设有一次角度正在做什么和从我使用$compile
时开始,第一次编译一切都是正确的,第二次一切都是错误的。但我无法在不删除$compile
语句的情况下编译一次,这会破坏一切!它看起来像Angular编译所有“在上升的路上”(即儿童优先)并将所有“在路上”(即父母第一)链接起来,但我无法证实。在预感我尝试返回预链接功能而不是postlink功能,但无济于事。我还尝试在elem.replaceWith(...)
函数之前调用link
调用并在link
函数内编译子代,但这也不起作用。
我的想法正在发生。我认为将删节置于链接功能会使一切变得混乱(虽然我被迫因为compile
没有范围)指令中的em> old clone,并且出于某种原因删除了它的子节点(例如,elem
和lElem
在引用时没有子节点)。一旦确认,我不确定如何确认或如何修复它。我初步通过注入$rootScope
并在编译函数中执行所有链接等进行了一些测试,但没有任何效果。不过,我不确定在编译和编译子范围之间是否存在任何差异。