如果您在单个DOM元素上有多个指令,并且它们应用的顺序很重要,您可以使用priority
属性来排序它们的应用程序。数字越高,优先级越高。如果不指定优先级,则默认优先级为0。
编辑:经过讨论,这是完整的工作解决方案。关键是要删除属性:element.removeAttr("common-things");
,以及element.removeAttr("data-common-things");
(如果用户在HTML中指定了data-common-things
)
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things");
element.removeAttr("data-common-things");
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
可在此链接查看可用的Plunker: http://plnkr.co/edit/Q13bUt?p=preview
或者:
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things");
element.removeAttr("data-common-things");
$compile(element)(scope);
}
};
});
演示
为什么我们需要设置terminal: true
和priority: 1000
(一个高数字)的解释:
当DOM准备就绪时,Angular会遍历DOM以识别所有已注册的指令,并根据priority
逐个编译这些指令,如果这些指令在同一元素上。我们将自定义指令的优先级设置为一个较高的数字,以确保它将被首先编译,并使用terminal: true
,其他指令将在此指令编译后跳过。
当我们的自定义指令被编译时,它将通过添加指令并删除自身来修改元素,并使用$compile服务来编译所有指令(包括那些被跳过的指令)。
如果我们不设置terminal:true
和priority: 1000
,则有可能在我们的自定义指令之前编译一些指令。当我们的自定义指令使用$compile编译元素时,会再次编译已经编译过的指令。这将导致不可预测的行为,特别是如果在我们的自定义指令之前编译的指令已经转换了DOM。
有关优先级和终端的更多信息,请查看如何理解指令的“终端”?
一个还修改模板的指令示例是ng-repeat
(priority = 1000),当ng-repeat
被编译时,ng-repeat
在其他指令应用之前复制模板元素。
感谢@Izhaki的评论,这里是ngRepeat
源代码的参考:https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceeded
。 - frapontilloelement.removeAttr("common-datepicker");
以避免无限循环。 - Khanh TOreplace: false
、terminal: true
和priority: 1000
,然后在compile
函数中设置所需的属性并移除我们的指令属性。最后,在compile
返回的post
函数中调用$compile(element)(scope)
。该元素将被常规编译,不使用自定义指令,但具有添加的属性。我的目标是不要删除自定义指令,并在一个过程中处理所有内容:这似乎是不可能的。请参考更新后的 plnkr:http://plnkr.co/edit/Q13bUt?p=preview。 - frapontillo$compile(element, null, 1000)(scope);
- Andreas