带有 ng-repeat 验证的 AngularJS 多个表单 [英] AngularJS multiple forms with ng-repeat validation

查看:23
本文介绍了带有 ng-repeat 验证的 AngularJS 多个表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 ng-form 作为父表单,使用子 mg-form 使用 ng-repeat 进行验证.

<div ng-repeat="字段中的字段"><div ng-form="subform"><input...></div>

并像这样验证:

if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) {//做点什么...}

(这是一个非常简单的例子,对于不同的输入类型和不同的名称,我有更多不同的子表单,例如 input[text] 被命名为 TextForm,input[numeric] 是 NumericForm 等)

如果只有现场,一切都按预期进行.但是如果 ng-repeat 生成多个字段,验证只会触发最后一个子表单,其他的会被忽略.

有没有办法循环遍历所有子表单以检查其中一个是否无效?

此外,我正在标记所有未填写的必填字段,如下所示:

if ($scope.form.$error.required) {angular.forEach($scope.form.$error.required,函数(对象,索引){$scope.form.$error.required[index].$setDirty();});}

所以如果我的字段是这样完成的:

....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }"....

即使有很多同名的子表单,它也会标记所有的子表单.

也许我可以对无效字段做类似的事情?虽然尝试了很多东西,但没有任何效果......

解决方案

对此的解决方案是创建一个指令,将 ngModelController 的错误分配给每个 ng-重复输入.

下面是获取每个子表单错误的可能实现.演示

JAVASCRIPT(指令)

 .directive('ngModelError', function($parse, $timeout) {返回 {要求: ['ngModel', 'form'],链接:功能(范围,元素,属性,ctrls){var ngModel = ctrls[0],ngForm = ctrls[1],fieldGet = $parse(attr.ngModelError),fieldSet = fieldGet.assign,字段 = fieldGet(范围);$超时(功能(){field.$error = ngModel.$error;field.ngForm = ngForm;字段集(范围,字段);});}};});

HTML

<div ng-form="subForm" ng-repeat="字段中的字段"ng-class="{'has-error': subForm.$invalid && form.$dirty}"><label class="control-label">{{field.label}}</label><input type="{{field.type}}" placeholder="{{field.placeholder}}"ng-model="field.model" name="field"ng-required="field.isRequired" class="form-control"ng-model-error="字段"/>

<br><button type="submit" class="btn btn-primary">提交</button></表单>

JAVASCRIPT(控制器)

请注意字段的结构:

 .controller('Ctrl', function($scope) {$scope.fields = {电子邮件: {类型:'电子邮件',占位符:'输入电子邮件',是必需的:真,标签:'电子邮件地址'},密码: {类型:'密码',占位符:'输入密码',是必需的:真,标签:'密码'}};$scope.submit = 函数(表单,字段){form.$dirty = true;if(form.$valid) {//做任何事} 别的 {//访问电子邮件字段的 ngFormconsole.log(fields.email.ngForm);//访问电子邮件字段的错误console.log(fields.email.$error);//访问 ngForm 以获取密码字段console.log(fields.password.ngForm);//访问密码字段错误console.log(fields.password.$error);}};})

I am using ng-form as a parent form and child mg-forms for validation with ng-repeat.

<div ng-form="form">
    <div ng-repeat="field in fields">
        <div ng-form="subform"><input...></div>
    </div>
</div>

And validating like this:

if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) {
    // Do something...
}

(this is very simplified example, I have more different subforms for different input types and with different names, e.g. input[text] is named as a TextForm, input[numeric] is NumericForm etc.)

Everything works as expected if there is only on field. But if ng-repeat generates multiple fields, validation triggers only the last subform, others gets ignored.

Is there a way of cycling through all subforms to check if one of them is invalid?

Also, I am marking all unfilled required fields like this:

if ($scope.form.$error.required) {
     angular.forEach($scope.form.$error.required,
         function (object, index) {
             $scope.form.$error.required[index].$setDirty();
         }
     );
}

So if my fields are done like this:

....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }"....

And it marks all the subforms even if there are many of the same ones with the same name.

Maybe I could do something similar with invalid fields? Though tried many things, nothing worked...

解决方案

A solution for this is to create a directive that assigns the ngModelController's error to a variable in each ng-repeat input.

Below is a possible implementation to get the errors of each subForm. DEMO

JAVASCRIPT (directive)

  .directive('ngModelError', function($parse, $timeout) {
    return {
      require: ['ngModel', 'form'],
      link: function(scope, elem, attr, ctrls) {
        var ngModel = ctrls[0],
            ngForm = ctrls[1],
            fieldGet = $parse(attr.ngModelError),
            fieldSet = fieldGet.assign,
            field = fieldGet(scope);

        $timeout(function() {
          field.$error = ngModel.$error;
          field.ngForm = ngForm;
          fieldSet(scope, field);
        });

      }
    };
  });

HTML

<form name="form" ng-submit="submit(form, fields)" novalidate>
  <div ng-form="subForm" ng-repeat="field in fields"
    ng-class="{'has-error': subForm.$invalid && form.$dirty}">
    <label class="control-label">{{field.label}}</label>
    <input type="{{field.type}}" placeholder="{{field.placeholder}}" 
      ng-model="field.model" name="field" 
      ng-required="field.isRequired" class="form-control" 
      ng-model-error="field" />
  </div>
  <br>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>

JAVASCRIPT (controller)

Please take note how the fields are structure:

  .controller('Ctrl', function($scope) {
    $scope.fields = {
      email: {
        type: 'email',
        placeholder: 'Enter email',
        isRequired: true,
        label: 'Email Address'
      }, 

      password: {
        type: 'password',
        placeholder: 'Enter password',
        isRequired: true,
        label: 'Password'
      }
    };

    $scope.submit = function(form, fields) {
      form.$dirty = true;

      if(form.$valid) {
        // do whatever
      } else {
        // accessing ngForm for email field
        console.log(fields.email.ngForm);
        // accessing errors for email field
        console.log(fields.email.$error);

        // accessing ngForm for password field
        console.log(fields.password.ngForm);
        // accessing errors for password field
        console.log(fields.password.$error);
      }
    };
  })

这篇关于带有 ng-repeat 验证的 AngularJS 多个表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆