javascript – 如何在child指令之前执行parent指令?

我正在寻找一个两个角度指令(父指令和子指令)来创建可排序和可克隆的小部件。预期的标记是:

<div class="widget-container" data-sortable-widgets>
      <section class="widget" data-cloneable-widget></section>
<div>

但是,子指令似乎在父级之前执行,在某个元素可用之前(由父级添加):

function SortableWidgetsDirective() {
    return {
        priority: 200,
        restrict: 'A',
        link: function ($scope, element, attrs) {
            element.find(".widget header").append($("<div class='widget-controls'></div>"));
            element.sortable({  });
        }
    };
}

function CloneableWidgetDirective() {
    return {
        priority: 100,
        restrict: 'A',
        link: function ($scope, element, attrs) {
            // This directive wrongfully executes first so widget-controls is no available
            element.find("header .widget-controls").append($("<div class='clone-handle'></div>"));
        }
    };
}

正如你可以看到,我尝试设置优先级,但我认为,因为它们在不同的元素,它不起作用。

我如何使父级首先执行?

推理

postLink()以相反的顺序执行,这意味着子指令的postLink()将在父进程(即深度优先)之前被调用。由于某些原因,这是默认行为(link()实际上是指postLink())。幸运的是,我们也有preLink(),其工作原理相反 – 我们可以利用这一点,我们的利益。

为了说明这一点 – 以下代码片段:

app.directive('parent', function($log) {
    return {
        restrict: 'E',
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                pre: function preLink(scope, iElement, iAttrs, controller) {
                    $log.info('parent pre');
                },
                post: function postLink(scope, iElement, iAttrs, controller) {
                    $log.info('parent post');
                }
            }
        }
    };
});

app.directive('child', function($log) {
    return {
        restrict: 'E',
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                pre: function preLink(scope, iElement, iAttrs, controller) {
                    $log.info('child pre');
                },
                post: function postLink(scope, iElement, iAttrs, controller) {
                    $log.info('child post');
                }
            }
        }
    };
});

…将输出以下内容:

> parent pre
> child pre
> child post
> parent post 

live on plunker

如果我们希望父指令的逻辑在孩子之前执行,我们将明确使用preLink():

function SortableWidgetsDirective() {
    return {
        restrict: 'A',
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                pre: function preLink(scope, iElement, iAttrs, controller) {
                    iElement.find(".widget header").append($("<div class='widget-controls'></div>"));
                    iElement.sortable({});
                },
                post: angular.noop
            }
        }
    };
}

function CloneableWidgetDirective() {
    return {
        restrict: 'A',
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                pre: function preLink(scope, iElement, iAttrs, controller) {
                    iElement.find("header .widget-controls").append($("<div class='clone-handle'></div>"));
                },
                post: angular.noop
            }
        }
    };
}

参考文献

> $compile服务于AngularJS文档。

Post Scriptum

>你是正确的,顺便说一下,优先级是用于共享相同元素的指令。
> angular.noop只是一个没有返回任何东西的空方法。如果您仍然想使用postLink()函数,那么只需放置函数声明,就像通常所做的那样,即:

post: function postLink(scope, iElement, iAttrs, controller) { ... }

>使用templateUrl作为“因为模板加载是异步的,编译/链接被挂起,直到模板被加载”[source].因此,执行顺序将被中断。您可以通过将模板内嵌在模板属性中来替代来解决这个问题。

http://stackoverflow.com/questions/22081140/how-to-execute-parent-directive-before-child-directive

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – 如何在child指令之前执行parent指令?