javascript 带有指令的 Angularjs 初始表单验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17011288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 06:46:01  来源:igfitidea点击:

Angularjs initial form validation with directives

javascriptangularjs

提问by GrahamB

I have a validation directive called valid-numberthat is used to set the validity of a form using $setValidity - this works fine for any text values that I type into the input box that have the directive applied to as an attribute.

我有一个名为的验证指令valid-number,用于使用 $setValidity 设置表单的有效性 - 这适用于我在输入框中键入的任何文本值,这些值将指令应用于作为属性。

The HTML is

HTML是

<form name="numberForm">
<input name="amount" type="text" ng-model="amount" required  valid-number /></form>

The directive is as follow

指令如下

angular.module('test',[]).directive('validNumber',function(){
            return{
                require: "ngModel",
                link: function(scope, elm, attrs, ctrl){

                    var regex=/\d/;
                    ctrl.$parsers.unshift(function(viewValue){
                        var floatValue = parseFloat(viewValue);

                        if(regex.test(viewValue)){
                            ctrl.$setValidity('validNumber',true);
                        }
                        else{
                            ctrl.$setValidity('validNumber',false);
                        }
                        return viewValue;
                    });
                }
            };
        });

However, I would also like the validation to be triggered and set the css to an invalid clsss if the value the input box is initialised to when the page is first loaded is invalid, eg if I set $scope.amount = 'not a number'I would expect the input box to have had the directive applied to it, but no joy. In order for not a numberto be highlighted as invalid I have to make a change to the contents of the input, which triggers the directive.

但是,如果第一次加载页面时输入框初始化的值无效,我也希望触发验证并将 css 设置为无效的 clsss,例如,如果我设置$scope.amount = 'not a number'我希望输入框有指令适用于它,但没有喜悦。为了not a number突出显示为无效,我必须对触发指令的输入内容进行更改。

How can I ensure the directive applies to whatever the <input>is initialised with?

如何确保指令适用于<input>初始化的任何内容?

A full code example is here;

完整的代码示例在这里;

http://jsfiddle.net/JW43C/5/

http://jsfiddle.net/JW43C/5/

回答by Stewie

$parsersarray contains a list of functions that will be applied to the value that model receives from the view (what user types in), and $formattersarray contains the list of functions that are being applied to the model value before it's displayed in the view.

$parsersarray 包含将应用于模型从视图接收的值的函数列表(用户键入的内容),$formattersarray 包含在模型值显示在视图中之前应用于模型值的函数列表。

In your directive you correctly used the $parsersarray, but you also need to add the $formattersarray if you want the initial value to be validated:

在您的指令中,您正确使用了$parsers数组,但$formatters如果您希望验证初始值,还需要添加数组:

angular.module('test',[]).directive('validNumber',function(){
  return{
    require: "ngModel",
    link: function(scope, elm, attrs, ctrl){
      var regex = /^\d$/;
      var validator = function(value){
        ctrl.$setValidity('validNumber', regex.test(value));
        return value;
      };

      ctrl.$parsers.unshift(validator);
      ctrl.$formatters.unshift(validator);
    }
  };
});

Demo plunker

演示 plunker

回答by Blackhole

You can simply call your verification function during the linking phase, like in this fiddle:

您可以在链接阶段简单地调用您的验证函数,就像在这个小提琴中一样

link: function(scope, elm, attrs, ctrl) {                       
    var regex=/\d/;
    var verificationFunction = function(viewValue) {
        var floatValue = parseFloat(viewValue);

        if(regex.test(viewValue)) {
            ctrl.$setValidity('validNumber',true);
            return viewValue;
        }
        else {
            ctrl.$setValidity('validNumber',false);
            return undefined;
        }
    };

    ctrl.$parsers.unshift(verificationFunction);
    verificationFunction();
}

回答by Maxim Zhukov

After (>=) angular 1.3.1 version was released you could implement that behaviour with a little bit correct way, following angular validation directives style (e.g. required, maxlength).

在 (>=) angular 1.3.1 版本发布后,您可以按照 angular 验证指令样式(例如requiredmaxlength)以正确的方式实现该行为。

In that case you have to append your validator as property of $validatorsarray and there are no need in $parsersor $formattersanymore:

在这种情况下,你必须要附加的验证作为财产$validators数组,有没有必要$parsers$formatters不再:

var app = angular.module('test', []);

app
  .directive('validNumber', function() {
    return {
      require: "ngModel",
      link: function(scope, elm, attrs, ctrl) {
        var regex = /^\d+$/;

        ctrl.$validators['validNumber'] = function(modelValue, viewValue) {
          return regex.test(viewValue);
        };
      }
    };
  });

app.controller('NumberCtrl', NumberCtrl);

function NumberCtrl($scope) {
  $scope.amount = '5z';
};
input.ng-invalid {
  background-color: #FA787E;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>

<div ng-app="test">
  <div ng-controller="NumberCtrl">

    <div ng-form name="numberForm">
      <input name="amount"
             type="text"
             ng-model="amount"
             required 
             valid-number />
      
      <span ng-show="numberForm.amount.$error.validNumber">
        Doesn't look like an integer
      </span>
    </div>        
  </div>
</div>