How to add validation attributes in an angularjs d

2020-02-10 16:04发布

问题:

I am trying to write an angular directive that adds validation attributes to the tag, but it doesn't seem to be working. Here is my demo. You will notice that "Is Valid" remains true if you delete the text in the second input box, but goes to false if you delete the text in the first input box.

http://plnkr.co/edit/Rr81dGOd2Zvio1cLYW8D?p=preview

Here is my directive:

angular.module('demo', [])
.directive('metaValidate', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.attr("required", true);
        }
    };
});

I'm guessing I am just missing something simple.

回答1:

All rules for validation of the form are being read in compilation phase of the form, so after making changes in a child node, you need to recompile form directive (form it's a custom directive in AngularJS). But do it only once, avoid infinite loops (your directive's 'link' function will be called again after form's compilation).

angular.module('demo', [])
.directive('metaValidate', function ($compile) {
    return {
        restrict: 'A',
        link: function (scope,element, attrs) {
          if (!element.attr('required')){
            element.attr("required", true);
            $compile(element[0].form)(scope);
          }
        }
    };
});

Working plunker: http://plnkr.co/edit/AB6extu46W4gFIHk0hIl?p=preview



回答2:

Be careful of infinite loops and recompiles, a better solution is here: Add directives from directive in AngularJS

angular.module('app')
  .directive('commonThings', function ($compile) {
    return {
      restrict: 'A',
      terminal: true, //this setting is important to stop loop
      priority: 1000, //this setting is important to make sure it executes before other directives
      compile: function compile(element, attrs) {
        element.attr('tooltip', '{{dt()}}');
        element.attr('tooltip-placement', 'bottom');
        element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
        element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html

        return {
          pre: function preLink(scope, iElement, iAttrs, controller) {  },
          post: function postLink(scope, iElement, iAttrs, controller) {  
            $compile(iElement)(scope);
          }
        };
      }
    };
  });

Working plunker is available at: http://plnkr.co/edit/Q13bUt?p=preview



回答3:

I know this is quite an old question, but for what it's worth, the angular docs describe ng-required which takes a boolean value. This solved a similar problem I was having.

http://docs.angularjs.org/api/ng/directive/input