通过另一个属性指令设置属性指令导致双重绑定

Setup a attribute directive via another attribute directive is causing double bindings

背景: 我想在我的项目中简化 <uib-tooltip> 指令的使用,主要是翻译文本并为工具提示设置更多选项。

对于翻译,我使用 Angular 翻译。我知道我可以直接将翻译过滤器 {{'TRANSLATIONKEY'|translate}}<uib-tooltip> 一起使用,但我也想在我的应用程序中简化工具提示的使用。

描述: 在通过 example-a 指令应用属性 example-b 时,由于 $compile 按钮上的点击事件将被绑定两次(点击按钮)。此外,指令的范围不是孤立的,否则来自控制器的更改将不再起作用。

期望: 我的期望是我可以在不发生双重绑定的情况下切换属性指令。

我还创建了一个 Plunkr 示例来演示我的问题,请参阅 https://plnkr.co/edit/jMwPzAqLY1XonJQbbIzT

有什么方法可以做到这一点,我愿意接受任何建议吗?

这会很好用。它只会调用一次点击方法。

HTML:

<button class="btn btn-default" example-a click-fn="clickButton()">

示例 A 指令:

/**
   * @ngdoc directive
   * @name app.directive:ExampleA
   *
   * @description
   * This directive set the attribute for the 2nd directive and remove itself from the element.
   */
  function ExampleA($log, $compile) {
    function linkFuntion($scope, $element, $attributes) {
      $log.info('Directive - ExampleA - executed');

      // To prevent "Maximum call stack size exceeded" error.
      $attributes.$set('example-a', null);

      // Sset new attribute "example-b" to trigger directive handling.
      $attributes.$set('example-b', ''); 

      // Compile the element causes double binding but must be done
      // cause otherwise the new attribute "example-b" is not
      // working.
      $compile($element)($scope);
      $element.bind("click", function(e){
          $scope.clickFn();
      });
    }

    return {
      restrict: 'A',
      scope : {
        clickFn: "&clickFn"
      },

      link: linkFuntion
    };
  }

设置指令的优先级高于其他指令,并使用 DDO:

terminal 属性
 function ExampleA($log, $compile) {
    function linkFuntion($scope, $element, $attributes) {
      $log.info('Directive - ExampleA - executed');

      // To prevent "Maximum call stack size exceeded" error.
      $attributes.$set('example-a', null);

      // Sset new attribute "example-b" to trigger directive handling.
      $attributes.$set('example-b', ''); 

      // Compile the element causes double binding but must be done
      // cause otherwise the new attribute "example-b" is not
      // working.
      $compile($element)($scope);
    }

    return {
      priority: 9999,
      terminal: true,
      restrict: 'A',
      link: linkFuntion
    };
  }

通过使用 terminal 属性,其他属性指令将不会在第一遍编译。它们只会在链接函数中被编译一次。

有关详细信息,请参阅 AngularJS Comprehensive Directive API Reference - terminal