6

相关:如何理解指令的“终端”?

为什么有人会在指令上设置 terminal: true 和优先级,而不是简单地删除较低优先级的指令?例如,他们可以写:

<tag directive-1 directive-2 directive-3></tag>

...并且他们可以将优先级:100 和终端:真添加到指令 3,这样只有指令 3 将应用于元素。

为什么不有人将他们的模板改为:

<tag directive-3></tag>

也许它在某些情况下通过允许将多个指令添加到一个元素并卸载决定哪些指令实际应用于 Angular 的工作来简化代码?

谢谢。

4

2 回答 2

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 上,但它们的优先级 + 终端选项将决定谁首先编译,以及何时发生链接。通常我们希望元素被克隆,并且为每个绑定复制 forli和 for指令,但这只有 在优先级低于 fake-repeat时才会发生。add-lettertadd-letter

案例 1:添加字母优先级为 0

为每个li生成的执行链接。

案例 2:添加字母优先级为 1001

链接在假重复之前执行,因此在嵌入发生之前执行。

案例 3:add-letter 优先级为 1001 且终端为真

编译在 fake-repeat 之前停止,因此该指令永远不会执行。

这是一个带有控制台日志记录的插件,用于进一步探索。

于 2013-09-25T05:03:48.770 回答
2

我相信终端的创建是为了与使用嵌入的指令或旨在替换所有元素内容的指令一起使用。

如果一个元素使用终端,那么它不希望在初始指令收集期间编译适用的指令。初始集合由 Angular 的引导过程或手动 $compile 触发。仅仅因为终端指令不希望低优先级指令编译,并不意味着它不希望指令稍后运行,这就是为什么 transclude 是一个完美的用例。

内容被编译并存储为链接函数,可以随时针对任何范围进行评估。这就是 ngRepeat 和 ngIf 的执行方式。

在编写使用嵌入的指令时,可以考虑是否也应该使用终端。

我不相信它在与不使用 transclude 的指令一起使用时非常有用。

于 2014-02-12T06:27:37.217 回答