Установка директивы атрибута через другую директиву атрибута вызывает двойные привязки - PullRequest
0 голосов
/ 09 мая 2018

Справочная информация: Я хочу упростить использование директивы <uib-tooltip> в моем проекте, чтобы в основном иметь переведенные тексты и устанавливать дополнительные параметры для всплывающих подсказок.

Для перевода я использую Angular Translate. Я знаю, что мог бы использовать фильтр перевода {{'TRANSLATIONKEY'|translate}} напрямую с <uib-tooltip>, но я также хочу упростить использование всплывающих подсказок в целом в моем приложении.

Описание: При применении атрибута example-b через директиву example-a из-за $ compile событие click на кнопке будет связано дважды (кнопка click). Кроме того, область действия директивы не изолирована, потому что иначе изменения в контроллере больше не будут работать.

Expectation: Я ожидаю, что смогу переключать директивы атрибутов без двойной привязки.

Я также создал пример Plunkr для демонстрации своей проблемы, см. https://plnkr.co/edit/jMwPzAqLY1XonJQbbIzT.

Есть ли способ добиться этого, я открыт для любых предложений?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Установите приоритет директивы выше, чем у других, и используйте свойство terminal DDO:

 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 другие директивы атрибута не будут скомпилированына первом проходе.Они будут скомпилированы только один раз в функции связывания.

Для получения дополнительной информации см. Справочник по API AngularJS - терминал .

0 голосов
/ 09 мая 2018

Это будет хорошо работать. Он будет вызывать метод click только один раз.

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
    };
  }
...