【问题标题】:Why use terminal: true instead of removing lower priority directives?为什么使用终端:真而不是删除较低优先级的指令?
【发布时间】:2013-09-28 23:03:39
【问题描述】:

相关:How to understand the `terminal` of directive?

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

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

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

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

<tag directive-3></tag>

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

谢谢。

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

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

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

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

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

    我认为它在与不使用 transclude 的指令一起使用时不是很有用。

    【讨论】:

      【解决方案2】:

      设置优先级和终端选项不是删除指令,而是声明编译和链接的顺序。大家都将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 才会发生这种情况 优先级低于 fake-repeat。

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

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

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

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

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

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

      这是一个plunker,带有控制台日志记录,以供进一步探索。

      【讨论】:

      • 但在案例 3 中,为什么不直接删除 fake-repeat 指令?
      • 案例 3 只是对可用选项及其效果的演示。通常情况 3 不是很有用,因此您只需删除虚假的重复。关键是如果没有可用的选项,您将无法获得高效的 ng-repeat。
      • 在您的 plunker 示例中,当 add-letter2 的优先级低于 fake-repeat 时,为什么要在 fake-repeat2 之前记录 Compile?
      • 谢谢。这非常适合用作“ng-repeat”而没有所有的手表开销。我发现的唯一一件事是通过添加“关键”元素来包含对象,然后执行 $element.before(clone);代替 $element.after(clone);跳过对对象不起作用的“revese”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      相关资源
      最近更新 更多