相关:如何理解指令的"终端"?
为什么有人会在指令上设置终端:true和优先级,而不是简单地删除优先级较低的指令? 例如,他们可以写:
<tag directive-1 directive-2 directive-3></tag>
。他们可以将优先级:100和终端:true添加到指令-3,以便只有指令-3将应用于元素。
为什么有人不将他们的模板更改为:
<tag directive-3></tag>
也许在某些情况下,它通过允许将多个指令添加到一个元素中并减轻决定哪些指令实际应用于 Angular 的工作来简化代码?
谢谢。
设置优先级和终端选项不是关于擦除指令,而是声明编译和链接的顺序。每个人都指出ng-repeat是优先级+终端+排除的主要例子,所以我将给出一个非常简化的ng-repeat版本:
app.directive('fakeRepeat', function($log) {
return {
priority: 1000,
terminal: true,
transclude: 'element',
compile: function(el, attr, linker) {
return function(scope, $element, $attr) {
angular.forEach(scope.$eval($attr.fakeRepeat).reverse(), function(x) {
var child = scope.$new();
child[attr.binding] = x;
linker(child, function(clone) {
$element.after(clone);
})
})
}
}
}
});
假重复指令可以这样使用:
<ul>
<li fake-repeat="things" binding="t" add-letter>{{ t }}</li>
<ul>
现在,额外的指令可以附加到包含假重复的同一个 li,但它们的优先级 + 终端选项将决定谁先编译,以及何时发生链接。通常我们希望克隆li
元素,并为每个绑定t
复制 add-letter
指令,但这只会在以下情况下发生add-letter
优先级低于假重复。
情况 1:添加字母优先级为 0
对生成的每个li
执行链接。
情况二:添加字母优先级为1001
链接在假重复之前执行,因此在排除发生之前执行。
情况 3:添加字母优先级为 1001,终端为 true
编译在假重复之前停止,因此永远不会执行指令。
这是一个带有控制台日志记录的 plunker,用于进一步探索。
我相信创建终端是为了使用使用嵌入的指令或旨在替换元素所有内容的指令。
如果元素使用终端,则它不希望在初始指令集合期间编译适用的指令。初始收集由 Angular 的引导过程或手动$compile触发。仅仅因为终端指令不希望编译优先级较低的指令,并不意味着它不希望指令稍后运行,这就是为什么 transclude 是一个完美的用例。
内容被编译并存储为链接函数,可以随时针对任何范围进行评估。这就是ngRepeat和ngIf的表现。
在编写使用嵌入的指令时,可以考虑是否也应该使用终端。
我不认为当它与不使用 transclude 的指令一起使用时它很有用。