AngularJS ng Требуемая пользовательская директива - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть небольшая директива для добавления класса required к ближайшей метке элемента формы. Он отлично работает с атрибутом required, но при использовании ng-required кажется, что директива не привязана к элементу.

Как динамически вызвать привязку директивы при изменении ng-required?

ПРИМЕЧАНИЕ Я не хочу добавлять дополнительную разметку к HTML, если это возможно, чтобы иметь одну глобальную директиву

var app = angular.module('app',[]);
app.controller('myController',function ($scope) {
  $scope.isRequired = false;
  
  $scope.$watch('isRequired', function () {
    angular.element('#html').text(angular.element('#required-element').html());
  })
});
app.directive('required', function () {
  return {
    restrict: 'A',
    link: function ($scope, $elem) {
      console.log('Linking');
      label = $elem.closest('.input-container').find('label');

      if (label.length) {
         label.addClass('required');
      }
    }
  };
});
.required:before {
  content: '*';
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app"ng-controller="myController">

  <div class="input-container">
      <label>Label</label>
      <input type="text" required/>
  </div>
  
  <div id="required-element" class="input-container">
      <label>Label Dynamic</label>
      <input type="text" ng-required="isRequired == true"/>
  </div>

  <label><input type="checkbox" ng-model="isRequired"/> Make required: {{isRequired | json}}</label>
  
  <hr/>
  <span id="html"></span>
</div>

1 Ответ

0 голосов
/ 12 февраля 2020

Как отметил @PetrAveryanov в комментариях, возможно $observe атрибутов в директиве отслеживать его изменения.

Тем не менее, нам кажется, что нам нужны 2 директивы. Один для статистики c required и один с наблюдением за ngRequired добавленным атрибутом

angular
  .module('app', [])
  .controller('myController',function ($scope) {
    $scope.isRequired = false;
  
    $scope.$watch('isRequired', function () {
      angular.element('#html').text(angular.element('#required-element').html());
    });
  })
  .factory('requiredLabelFactory', function () {
    toggleLabel = function ($elem, labelState) {
      label = $elem.closest('.input-container').find('label');

      if (label.length) {
         label.toggleClass('required', labelState);
      }
    };
    
    return {
      toggleLabel: toggleLabel
    };
  })
  .directive('required', function (requiredLabelFactory) {
    return {
      restrict: 'A',
      link: function ($scope, $elem) {
        requiredLabelFactory.toggleLabel($elem, true);
      }
    }
  })
  .directive('ngRequired', function (requiredLabelFactory) {
    return {
      restrict: 'A',
      link: function ($scope, $elem, attr) {
        attr.$observe('required', function(newVal) {
          requiredLabelFactory.toggleLabel($elem, newVal);
        });
      }
    };
  });
.required:before {
  content: '*';
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="app"ng-controller="myController">

  <div class="input-container">
      <label>Label</label>
      <input type="text" required/>
  </div>
  
  <div id="required-element" class="input-container">
      <label>Label Dynamic</label>
      <input type="text" ng-required="isRequired == true"/>
  </div>

  <label><input type="checkbox" ng-model="isRequired"/> Make required: {{isRequired | json}}</label>
  
  <hr/>
  <span id="html"></span>
</div>
...