AngularJS中经过验证的表单控件的方法

时间:2014-04-01 16:06:41

标签: forms angularjs validation angularjs-directive

我的队友和我正在学习AngularJS,目前正在尝试进行一些简单的表单字段验证。我们意识到有很多方法可以做到这一点,我们已经尝试了

  1. 通过验证过滤器输入
  2. 使用控制器和验证服务/工厂的组合
  3. 输入元素的验证指令
  4. 包含标签,输入和错误输出元素的指令
  5. 对我而言,指令方法似乎是最“正确”的。对于#3,我们遇到了必须将验证结果传递给错误元素(span兄弟)的问题。做一些范围杂耍很简单,但是将span放在指令中似乎“更正确”,并捆绑整个表单控件。我们遇到了几个问题,我希望StackOverflow社区对我们的解决方案提出意见和/或澄清任何误解。

    var PATTERN_NAME = /^[- A-Za-z]{1,30}$/;
    
    module.directive("inputName", [
      function () {
        return {
          restrict: "E",
          require: "ngModel",
          scope: {
            fieldName: "@",
            modelName: "=",
            labelName: "@",
            focus: "@"      
          },
          template: '<div>' +
            '<label for="{{fieldName}}">{{labelName}}</label>' +
            '<input type="text" ng-model="modelName" id="{{fieldName}}" name="{{fieldName}}" placeholder="{{labelName}}" x-blur="validateName()" ng-change="validateName()" required>' +
            '<span class="inputError" ng-show="errorCode">{{ errorCode | errorMsgFltr }}</span>' +
            '</div>',
          link: function (scope, elem, attrs, ngModel)
          {
            var errorCode = "";
    
            if (scope.focus == 'yes') {
              // set focus
            }
    
            scope.validateName = function () {
              if (scope.modelName == undefined || scope.modelName == "" || scope.modelName == null) {
                scope.errorCode = 10000;          
                ngModel.$setValidity("name", false);
              } else if (! PATTERN_NAME.test(scope.modelName)) {
                scope.errorCode = 10001;            
                ngModel.$setValidity("name", false);
              } else {
                scope.errorCode = "";
                ngModel.$setValidity("name", true);
              }
            };
          }
        };
      }
    ]);
    

    用作

    <form novalidate name="addUser">
      <x-input-name
        label-name="First Name" 
        field-name="firstName" 
        ng-model="firstName"
        focus="yes"
        model-name="user.firstName">
      </x-input-name>
    
      <x-input-name 
        label-name="Last Name" 
        field-name="lastName" 
        ng-model="lastName"
        model-name="user.lastName">
      </x-input-name>
      ...
    </form>
    

    首先,因为AngularJS指令会覆盖forminput,所以我们需要访问ngModel API(ngModelController)以允许现在嵌套的input能够将有效性传达给父FormController。因此,我们必须require: "ngModel",它成为ngModel函数的link选项。

    其次,即使fieldNamengModel被赋予相同的值,我们也必须单独使用它们。单向绑定(1WB)fieldName用作属性值。我们发现我们无法在ngModel指令中使用花括号。此外,我们无法使用带有ngModel 的1WB输入,我们无法使用双向绑定(2WB)输入,其值应为静态。如果我们使用单个2WB输入,则模型可以正常工作,但idname等属性将成为赋予表单控件的值。

    最后,因为我们有时会以相同的形式重复使用该指令(例如,名字和姓氏),所以我们必须传递像focus参数这样的属性。

    就个人而言,我还希望在onblur函数中看到使用JavaScript绑定的onchangelink事件,但我不确定如何从内部访问模板标记link,特别是在更大的DOM之外/不知道。

0 个答案:

没有答案