我目前正在编写一些 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
};
}
};
});
并且在这个 Plunkr上。现在,正如所写(好吧,充实),如果您尝试嵌套它们,这些指令将不起作用。内部指令最终将其嵌入的元素完全删除。但是,如果我替换elem.replaceWith(...)
为lElem.replaceWith(...)
(在 Plunkr 中 Javascript 文件的第 36 行),一切都很好,我可以嵌套任意多次。为什么会这样?这里有什么区别?我知道它elem
没有编译并且lElem
是,但这实际上意味着什么以及它如何影响我的代码?此外,是否不鼓励在link
函数中进行 DOM 操作?
我试过的。我尝试自己调试它,看起来对于内部指令,编译函数被调用了两次(我假设一次来自任何角度正在做的事情,一次来自我使用$compile
它时),它第一次编译所有东西是正确的,第二次一切都错了。但是我不能让它只编译一次而不删除$compile
语句,这会破坏一切!看起来 Angular 会“在上升过程中”(即孩子优先)编译所有内容,并“在下降过程中”(即父母优先)链接所有内容,但我无法确认这一点。凭直觉,我尝试返回 prelink 函数而不是 postlink 函数,但无济于事。我'elem.replaceWith(...)
link
link
功能,但这也不起作用。
我认为正在发生的事情。我认为通过在指令中获取旧克隆并出于某种原因删除其子代(并且在引用时没有子代,因为) ,将嵌入放在链接函数中会搞砸一切(尽管我被迫这样做,因为compile
没有范围)实例)。我不确定如何确认或确认后如何修复它。我初步通过在编译函数中注入并执行所有链接等进行了一些测试,但没有任何效果。不过,我不确定编译它和使用子范围编译之间是否有任何区别。elem
lElem
$rootScope