假设我有两个名为myFoo
和myBar
的属性指令。这些指令使用restrict: 'A'
定义。
然后我有一个元素
<div my-foo my-bar></div>
编译/链接函数的调用顺序是什么?在my-foo
编译之前是否始终会调用my-bar
编译?
答案 0 :(得分:6)
除了@ valepu之外,这里的答案是DDO(指令定义对象)的priority
属性的描述:
TL; DR 默认priority
为0
,如果您希望更改元素编译的顺序,则必须增加{{} 1}}用于元素。
当在单个DOM元素上定义了多个指令时, 有时需要指定指令的顺序 适用。优先级用于在指令之前对指令进行排序 编译函数被调用。优先级定义为数字。 首先编译具有更高数字优先级的指令。 预链接功能也按优先级顺序运行,但后链接 函数以相反的顺序运行。指令的顺序与 相同的优先级未定义。默认优先级为0。
在您的情况下,如果您没有为指令指定priority
,则首先编译priority
,然后编译my-bar
。但是,请注意控制器首先被初始化,然后是my-foo
,然后是pre
链接功能。此外,顺序在这里很重要:Angular交替编译指令。以下是我的post
打印,显示了该过程:
console.log
如果你想玩,我已经设置了Plunker。
现在,如果您将bar controller
foo controller
pre bar
pre foo
post foo
post bar
更改为priority
,您将获得以下输出:
priority: 1
如您所见,它从foo controller
bar controller
pre foo
pre bar
post bar
post foo
开始,然后转到myFoo
。所以myBar
现在有更高的优先级。
更新1
问题:
你如何处理静坐状态,其中两个不同的供应商指令(A和B)相互依赖,执行顺序很重要?是否可以在不改变vedor设置的情况下进行?
我建议按如下方式实现装饰器:
myFoo
通常,装饰器拦截服务的创建,允许它覆盖或修改服务的行为。但是,您也可以如上所示装饰您的指令。在装饰器中,您可以根据需要设置优先级以影响执行顺序。据我所知,app.config(function($provide) {
$provide.decorator('myFooDirective', function($delegate) {
var directive = $delegate[0];
directive.priority = 9;
return $delegate;
});
});
属性是控制指令应用顺序的唯一方法。使用装饰器时,您可以修改/覆盖priority
属性,但不能直接修改它的设置,以防您不想使用DDO。
上面的Plunker也使用装饰器实现进行了更新。
答案 1 :(得分:3)
没有, 指令有一个称为“优先级”的字段,它在必须编译时告诉角度。优先级越大,编译越早。因此,在您的情况下,指令将始终以相同的顺序编译(无论您如何在标记中写入它们),此顺序取决于它们的优先级字段(默认为0)。
来自https://docs.angularjs.org/api/ng/service/$compile
<强>优先强>
当在单个DOM元素上定义了多个指令时, 有时需要指定指令的顺序 适用。优先级用于在指令之前对指令进行排序 编译函数被调用。优先级定义为数字。 首先编译具有更高数字优先级的指令。 预链接功能也按优先级顺序运行,但后链接 函数以相反的顺序运行。指令的顺序与 相同的优先级未定义。默认优先级为0。
var myModule = angular.module(...);
myModule.directive('directiveName', function factory(injectables) {
var directiveDefinitionObject = {
priority: 0, //This is the priority field
/* ....... */
};
return directiveDefinitionObject;
});
本文似乎很好地解释了优先级在不同情况下的工作原理:http://www.newyyz.com/blog/2014/12/15/understanding-priorities-in-angularjs-directive-definition-objects/