【问题标题】:Setup a attribute directive via another attribute directive is causing double bindings通过另一个属性指令设置属性指令会导致双重绑定
【发布时间】:2018-05-09 10:53:14
【问题描述】:

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

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

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

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

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

有什么方法可以实现吗,我愿意接受任何建议吗?

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    将指令的优先级设置为高于其他指令的优先级,并使用 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

    【讨论】:

      【解决方案2】:

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

      HTML:

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

      指令示例:

      /**
         * @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
          };
        }
      

      【讨论】:

      • 这解决了一个问题,但引发了两个其他问题,不使用本机 ng-click,另一方面,由于其他点击处理程序超出了 AngularJS 的范围,计数器仅在 HTML 中更新,因为间隔并且需要 $apply。谢谢老兄。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 2013-06-23
      • 2016-03-05
      • 2016-11-04
      • 2016-11-19
      • 2023-03-09
      • 2016-04-04
      相关资源
      最近更新 更多