输入永远不会从Angular获得ng-invalid-class

时间:2016-08-26 09:41:34

标签: javascript angularjs validation

我们通过额外指令注册custom-form-elements的自定义验证方法:

<ng-form name="validatorTestForm">
    <our-input-directive name="validatorTest"
                         ng-model="ourModel"/>
    </our-input-directive>
    <our-validator-directive name="validatorTest"
                             form="validatorTestForm"
                             ng-model="ourModel">
    </our-validator-directive>
</ng-form>

它通过属性获取所有信息,以了解要验证哪种形式的输入;然后我们通过启动指令来连接它:(剥离版本)

registerValidator(ourModel.form, 'validatorTest');

function registerValidator(form, inputName) {
    var validationModel = form[inputName];

    validationModel.$validators.testValidator = function (modelValue) {
        // validate to true when there are more then two characters entered
        return modelValue.length > 2;
    };
}

我们的输入指令非常简单:

angular.directive('ourInputDirective', function() {
    return {
        restrict: 'E',
        template: '<input type="text" ng-model="model">',
        scope: {
            model: '=?ngModel'
        }
    }
});

所以我们运行它,Angular发挥它的魔力,并在form-element和input-element中添加吨css-classes,当我们输入某些内容时。进入输入,它正确地触发验证。表单元素获得了css-class-ng-valid&#39;什么时候它有效且无效的&#39;什么时候不是。

输入howewer,只有类&ng; ng-valid&#39;永远不会变得无效!
那么为什么会这样,我怎样才能改变它,以反映输入css类的模型变化?


我们想要利用“无效”&#39;用于更改输入样式的类。

3 个答案:

答案 0 :(得分:1)

使用ng-model https://docs.angularjs.org/api/ng/directive/ngModel

  

ngModel负责:

     
      
  • 将视图绑定到模型中,其他指令如input,textarea或select require。
  •   
  • 提供验证行为(即必需,号码,电子邮件,网址)。
  •   
  • 保持控件的状态(有效/无效,脏/原始,触摸/未触摸,验证错误)。
  •   
  • 在元素上设置相关的css类(ng-valid,ng-invalid,ng-dirty,ng-pristine,ng-touching,ng-untouched,ng-empty,ng-not-empty),包括动画
  •   
  • 使用其父表单注册控件。
  •   

这是一个像你一样的工作方式。 https://plnkr.co/edit/yWlZln2TekdCAhrZ6iEG?p=preview

function customValidator() {
   var directive = {
      require: '^form',
      link: link
   };
   return directive;

   function link(scope, element, attrs, formCtrl) {
      modelCtrl = formCtrl[attrs['name']];
      modelCtrl.$validators.testValidator = function (modelValue, viewValue) {
        var value = modelValue || viewValue;
        if(modelCtrl.$isEmpty(value)){
          return false;
        }
        return value.length > 2;
      };
   }
}

答案 1 :(得分:0)

正如krutkowski86所建议的那样尝试使用ng-model指令而不是你正在做的方式,下面是一个例子

<ng-form name="validatorTestForm">
    <input type="text" name="validatorTest" ng-model="MyVar" validator/>
</ng-form>


angular.module('yourModule').directive('validator', validator);

function validator() {
   var directive = {
      require: 'ngModel',
      link: link
   };
   return directive;

   function link(scope, element, attrs, ngModel) {
      ngModel.$validators.testValidator = function (modelValue) {
      // validate to true when there are more then two characters entered
      return modelValue.length > 2;
      };
   }
}

请参阅我的Plunker以获取示例https://plnkr.co/edit/mErINFdPt0odIOdu4Em2?p=preview

答案 2 :(得分:0)

经过一些测试,我们发现了问题:

虽然我们的验证人指令&#39;正在使用输入的ngModel,它没有使用ngModel的实例!这是由包含输入的指令上的隔离范围引起的。 (我没有在示例中添加,因为从未将其视为一个问题......)因此更改了&#39; our-validator-directive&#39;的ngModel。没有冒泡到原来的那个。

你真的必须链接到原来的,很容易实现的:

ngModelCtrl = form[nameOfTheInput]

而不是使用所需的ngModel,它被传递到validators指令
[我编辑了这个例子。 ]