【问题标题】:Angularjs initial form validation with directivesAngularjs 带有指令的初始表单验证
【发布时间】:2013-06-09 15:41:30
【问题描述】:

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

HTML 是

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

指令如下

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;
                    });
                }
            };
        });

但是,如果第一次加载页面时输入框初始化的值无效,我也希望触发验证并将 css 设置为无效的 clsss,例如,如果我设置 $scope.amount = 'not a number' 我希望输入框已经应用了指令,但没有任何乐趣。为了使not a number 被突出显示为无效,我必须更改输入的内容,这会触发指令。

如何确保该指令适用于 &lt;input&gt; 的初始化对象?

完整的代码示例在这里;

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

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

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

    在您的指令中,您正确使用了 $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

    【讨论】:

    • 非常棒的帖子,它突出了重要的细节,例如在文档中很难找到的 $parsers 和 $formatters。
    • 刚刚进入复杂的跨领域验证,这篇文章挽救了一天 - 或者把一天变成了几分钟嘿!
    • 你拯救了我的一天。谢谢!
    【解决方案2】:

    您可以在链接阶段简单地调用您的验证函数,例如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();
    }
    

    【讨论】:

      【解决方案3】:

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

      在这种情况下,您必须将验证器附加为 $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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-23
        • 1970-01-01
        • 2013-02-09
        • 2016-01-26
        • 2011-06-12
        • 1970-01-01
        相关资源
        最近更新 更多