相关:How to understand the `terminal` of directive?
为什么有人会设置terminal:true和指令的优先级而不是简单地删除优先级较低的指令?例如,他们可以写:
<tag directive-1 directive-2 directive-3></tag>
...并且他们可以添加优先级:100和terminal:true到指令-3,因此只有指令-3才会应用于元素。
为什么不会有人改为将模板更改为:
<tag directive-3></tag>
在某些情况下,通过允许将多个指令添加到元素并卸载决定哪些实际应用于Angular的工作,它可能简化了代码?
感谢。
答案 0 :(得分:5)
设置优先级和终端选项不是关于擦除指令,而是声明编译和链接的顺序。每个人都指向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
元素以及为每个绑定add-letter
复制t
指令,但这只会在add-letter
时发生。
优先级低于假重复。
为每个生成的li
执行链接。
链接在假重复之前执行,因此在转录发生之前执行。
编译在伪重复之前停止,因此永远不会执行该指令。
这是一个带有控制台日志记录的plunker以供进一步探索。
答案 1 :(得分:2)
我认为创建终端是为了使用指令来使用意图替换所有元素内容的指令。
如果元素使用终端,那么它不希望在初始指令集合期间编译适用的指令。初始集合由Angular的引导过程或手动$ compile触发。仅仅因为终端指令不希望编译较低优先级的指令,并不意味着它不希望指令稍后运行,这就是为什么transclude是一个完美的用例。
内容被编译并存储为链接函数,可以随时根据任何范围进行评估。这就是ngRepeat和ngIf的表现。
在编写使用转义的指令时,可以考虑是否应该使用终端。
我不相信它与不使用transclude的指令一起使用时非常有用。