gpt4 book ai didi

javascript - 如何在子指令之前执行父指令?

转载 作者:行者123 更新时间:2023-12-03 02:21:57 25 4
gpt4 key购买 nike

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

<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 文档上的服务。
<小时/>

后记

  • 顺便说一句,您是对的 - priority 旨在与共享相同元素的指令一起使用。

  • angular.noop 只是一个空方法,不返回任何内容。如果您仍然想使用 postLink() 函数,只需像通常那样放置函数声明即可,即:

    post: function postLink(scope, iElement, iAttrs, controller) { ... }
  • 请注意 templateUrl 的使用,如“由于模板加载是异步的,因此编译/链接将暂停,直到加载模板” [source] 。结果,执行顺序就会被打乱。您可以通过在 template 属性中包含内联模板来解决此问题。

关于javascript - 如何在子指令之前执行父指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22081140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com