4

我目前正在编写一些 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(...)linklink功能,但这也不起作用。

我认为正在发生的事情。我认为通过在指令中获取旧克隆并出于某种原因删除其子代(并且在引用时没有子代,因为) ,将嵌入放在链接函数中会搞砸一切(尽管我被迫这样做,因为compile没有范围)实例)。我不确定如何确认或确认后如何修复它。我初步通过在编译函数中注入并执行所有链接等进行了一些测试,但没有任何效果。不过,我不确定编译它和使用子范围编译之间是否有任何区别。elemlElem$rootScope

4

0 回答 0