AngularJS中多个属性指令的编译和链接顺序?

时间:2015-11-15 08:31:30

标签: javascript angularjs

假设我有两个名为myFoomyBar的属性指令。这些指令使用restrict: 'A'定义。

然后我有一个元素

<div my-foo my-bar></div>

编译/链接函数的调用顺序是什么?在my-foo编译之前是否始终会调用my-bar编译?

2 个答案:

答案 0 :(得分:6)

除了@ valepu之外,这里的答案是DDO(指令定义对象)的priority属性的描述:

TL; DR 默认priority0,如果您希望更改元素编译的顺序,则必须增加{{} 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/