在指令链接功能中修改的表单字段不再正确验证?

时间:2016-02-26 03:12:20

标签: angularjs

我有一个input元素,我有ng-required ng-pattern="/[0-9]{5}/"

它还有一个添加错误消息的指令,它具有以下链接功能和其他相关属性:

   return {
        scope: {},
        require: ['^^form', 'ngModel'],
        link: function(scope, element, attrs, ctrls) {
            // Places error message element after input element.
            var el = angular.element('<span>')
                .append(element.clone().removeAttr('mp-validated-field')) // else recurses
                .append('<span ng-show="showError" class="errorMsg">{{ error }}</span>');
            el = el[0].innerHTML;

            var tmp = $compile(el)(scope);
            element.replaceWith(tmp);
            element = tmp;
            ctrls[0].$addControl(ctrls[1]);
        },
        controller: // etc

这里应该发生的是,作为错误消息的span被指令自动放在input元素之后。如上所述,这种情况会发生,但是我必须使用$addControl来使formController在此之后重新注册输入。

当我使用空白输入运行时会发生什么(因此它应该失败required)是这个字段的formController的$error哈希包含{ {1}},也就是说它认为只有模式验证,没有必要的验证,并且模式验证正在通过,尽管它是正则表达式{pattern: false}(zipcode)。

我在这里缺少什么?

编辑:我将ng-required和ng-pattern指令移到了我的自定义指令之前,现在它识别了它们,但是它每次都无论如何都需要随意地执行ng ...是否是空白。

1 个答案:

答案 0 :(得分:1)

尝试此解决方案jsfiddle

angular.module('ExampleApp', [])
  .controller('ExampleController', function($scope) {

  })
  .directive('myError', function($compile) {
    return {
      restrict: "A",
      require: ['ngModel'],
      scope: {
        ngModel: "="
      },
      link: function(scope, elem, attr) {
        var span = angular.element('<div ng-show="showError" class="error">{{error}}</div>');
        elem.after(span);
        $compile(span)(scope);
        scope.error = 'Zip code must be not 0000';
        scope.$watch('ngModel', function(val) {
          if (val == '00000')
            scope.showError = true;
          else
            scope.showError = false;
        });
      }
    }
  });
.error {
  color: red;
  font-style: italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="ExampleApp">
  <div ng-controller="ExampleController">
    <form name="testForm">
      <input type="text" ng-model="zip" name="zip" my-error ng-pattern="/[0-9]{5}/" required>
      <div ng-show='testForm.zip.$error.required' class='error'>Is required</div>
      <div ng-show='testForm.zip.$error.pattern' class='error'>Invalid pattern</div>
      <br>
      <input type="text" ng-model="zip2" name="zip2" ng-pattern="/[0-9]{5}/" required my-error>
      <div ng-show='testForm.zip2.$error.required' class='error'>Is required</div>
      <div ng-show='testForm.zip2.$error.pattern' class='error'>Invalid pattern</div>
    </form>
  </div>
</div>

但对于复杂的自定义检查,我建议使用use-form-error

jsfiddle上的实例。

angular.module('ExampleApp', ['use', 'ngMessages'])
  .controller('ExampleController', function($scope) {

  });
.errors {
  color: maroon
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdn.rawgit.com/Stepan-Kasyanenko/use-form-error/master/src/use-form-error.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular-messages.min.js"></script>

<div ng-app="ExampleApp">
  <div ng-controller="ExampleController">

    <form name="myForm" use-form-error="formInvalid" use-error-expression="digit==9">
      <div ng-messages="myForm.$error" style="color:maroon">
        <div ng-message="formInvalid">You form is not valid</div>
      </div>
      <label>Your number should be even, not divisible by three and should not be 6,7,9:</label>
      <input type="text" ng-model="digit" name="myDigit" ng-minlength="1" ng-maxlength="20" required use-form-error="isEven" use-error-expression="digit%2==0" />
      <span use-form-error="isDividedThree" use-error-expression="digit%3==0" use-error-input="myForm.myDigit"></span>
      <span use-form-error="formInvalid" use-error-expression="digit==7" use-error-input="myForm.myDigit"></span>
      <span use-form-error="formInvalid" use-error-expression="digit==6"></span>
      <pre>myForm.myDigit.$error = {{ myForm.myDigit.$error | json }}</pre>

      <div ng-messages="myForm.myDigit.$error" ng-messages-multiple="true" style="color:maroon">
        <div ng-message="required">You did not enter a digit</div>
        <div ng-message="minlength">Your digit is too short</div>
        <div ng-message="maxlength">Your digit is too long</div>
        <div ng-message="isEven">Your digit is even</div>
        <div ng-message="isDividedThree">Your digit is divided by three</div>
      </div>
    </form>

  </div>
</div>