Подтвердить что ты не робот

Динамически добавлять атрибуты angular к элементу из директивы

Я пытаюсь создать директиву, изменяющую статус загрузки на кнопках для медленных вызовов ajax. В основном идея состоит в том, чтобы установить атрибут "ng-loading" на элемент кнопки, и пусть директива добавит остальную часть материала.

Это html-код:

<button class="btn btn-primary" name="commit" type="submit" ng-loading="signupLoading">
  Submit
</button>

И это код директивы:

.directive('ngLoading', ['$compile',  function($compile) {
  return {
    restrict: 'A',
    replace: false,
    terminal: true,
    link: function(scope, element, attrs) {
      element.attr('ng-class', '{loading:' + attrs['ngLoading'] +'}');
      element.attr('ng-disabled', attrs['ngLoading']);
      element.append(angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>'));
      $compile(element.contents())(scope);
    }
  };
}]);

Все выглядит правильно в визуализированном HTML, но атрибуты, добавленные в директиве, вообще не работают. Я могу переместить эти атрибуты в HTML-код, и все работает отлично, но это довольно много избыточный код во многих местах.

Я ссылался на директиву post Angular для динамического набора атрибутов на существующие элементы DOM, но это не решает мою проблему.

Любые комментарии/предложения приветствуются. Спасибо заранее.

4b9b3361

Ответ 1

Вам не нужно перекомпилировать эту директиву, если все, что вам нужно, - это некоторые манипуляции с DOM, вы можете добавлять и удалять класс в отношении изменений свойства scope. Вместо этого вы можете использовать $watch.

JAVASCRIPT

.directive('ngLoading', function() {
  return function(scope, element, attrs) {
    var img = angular.element('<img class="loading-icon" src="/assets/images/loading-icon.gif"/>');
    element.append(img);
    scope.$watch(attrs.ngLoading, function(isLoading) {
       if(isLoading) {
         img.removeClass('ng-hide');
         element.addClass('loading');
         element.attr('disabled', '');
       } else {
         img.addClass('ng-hide');
         element.removeClass('loading');
         element.removeAttr('disabled');
       }
    });
  };
});

Примечание. Ваш код не работает, поскольку он компилирует содержимое элементов, а не сам элемент, в который вы прикрепляете атрибуты, которые вы внедрили.

попробуйте $compile(elem)(scope);, и он должен работать корректно, но я не рекомендую его, потому что каждый элемент с такой директивой придется снова скомпилировать.

UPDATE: перед использованием $compile удалите атрибут 'ngLoading' для элемента, чтобы предотвратить бесконечную компиляцию.

elem.removeAttr('ng-loading');
$compile(elem)(scope);