【问题标题】:Angular reactive form custom validation using FormBuilder使用 FormBuilder 的 Angular 反应式表单自定义验证
【发布时间】:2018-08-21 17:40:37
【问题描述】:

我有一个名为 productionControlValidator 的自定义验证器函数。

如果我这样设置表单,一切正常:

this.validTest = new FormGroup({
    isdrawing: new FormControl(true),
    inventoryControl: new FormControl(null)
}, { validators: productionControlValidator });

但是,如果我使用这样的表单构建器设置表单:

this.validTest = this.fb.group({
    isdrawing: true,
    inventoryControl: null
}, { validators: productionControlValidator });

其中fb在构造函数中定义为private fb: FormBuilder, 那么验证不起作用。 “不起作用”是指表单的有效属性不正确,并且在控制台中我看不到预期的输出(使用第一种方法确实显示)。

我是不是在第二种方法中正确定义了验证器(如果是这种情况,应该如何定义),还是 FormBuilder 有什么东西导致自定义验证器不可用?

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

    更多信息--->DEMO

    在组件中使用自定义验证服务

    import {CustomValidationService } from './custom.service'
    
    this.validTest = this.fb.group({
        name: [null, [Validators.required, CustomValidationService.nameValidator],
        inventoryControl: [null, [CustomValidation]]
    });
    

    您可以将custom-validation-service 创建为:

    @Injectable()
    export class CustomValidationService {
        // Name validation 
            static nameValidator(control: FormControl) {
                if (control.value) {
                    const matches = control.value.match(/^[A-Za-z\s]+$/);
                    return matches ? null : { 'invalidName': true };
                } else {
                    return null;
                }
            }
    }
    

    【讨论】:

    • 这里的想法是我希望能够验证组,而不是个人控制。组验证器可以访问多个控件来执行验证。当使用new FormGroup(... 设置它时,验证器会正确访问所有内容并正确验证。我不想验证单个控件。
    • 但是组验证不是个好主意。您不能对单个自定义验证进行分类。
    • 为什么组验证不是一个好主意?它是官方 Angular 文档的一部分:angular.io/guide/form-validation#cross-field-validation
    【解决方案2】:

    尝试验证器而不是自定义验证器的验证器 文档:https://angular.io/api/forms/AbstractControl#root

    (validator ValidatorFn | null) 确定 此控件的同步有效性。

    this.validTest = this.fb.group({
        isdrawing: true,
        inventoryControl: null
    }, { validator: productionControlValidator });
    

    【讨论】:

      【解决方案3】:

      formGroup 中的 valueChanges 时触发表单验证。

      示例如下:Reactive form custom validators

      一旦更改表单的值,我们就可以触发整个表单的表单验证。

      这是示例类:

      import { Component, OnInit } from '@angular/core';
      import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
      
      @Component({
        selector: 'my-app',
        templateUrl: './app.component.html',
        styleUrls: [ './app.component.css' ]
      })
      export class AppComponent implements OnInit  {
      
        validTest: FormGroup;
        hasError = false;
      
        constructor(private fb: FormBuilder) {
        }
      
        ngOnInit() {
          this.validTest = this.fb.group ({
            isdrawing: [true, [Validators.required]],
            inventoryControl: ['10', [Validators.required, Validators.pattern('[0-9]*')]]
          });
      
          this.validTest.valueChanges.subscribe(form => {
            if(form) {
              this.productionControlValidator(form);
            }
          });
        }
      
        private productionControlValidator(form) {
          // custom validations for form controls
      
          if(form) {
            this.hasError = this.validTest.invalid;
          }
        }
      }
      

      示例 html 模板:

      <form [formGroup]="validTest">
        <input 
          type="checkbox"
          formControlName="isdrawing"/>
      
          <input
            type="text"
            formControlName="inventoryControl"
          />
      
          <div *ngIf="hasError">Form contains errors !!!</div>
      </form>
      

      【讨论】:

        【解决方案4】:

        如果你想要组验证方法试试这个

         validateAllFormFields(formGroup: any) {         //{1}
            Object.keys(formGroup.controls).forEach(field => {  //{2}
              const control = formGroup.get(field);             //{3}
                if (control instanceof FormControl) {             //{4}
                 control.markAsDirty({ onlySelf: true });
                 } else if (control instanceof FormGroup) {        //{5}
                 this.validateAllFormFields(control);            //{6}
              }
           });
        }
        
        
        
        save(data: any) {
            if (this.validTest.valid) {
        
            } else {
             this.validateAllFormFields(this.validTest);
          }
        }
        

        【讨论】:

          【解决方案5】:

          基本上以 Angular 形式进行验证是简单的部分。

          在 app.component.ts 文件中:

          你需要添加

          import { FormGroup, FormBuilder, Validators } from '@angular/forms';
          

          之后

          ngOnInit() {

          this.registerForm = this.formBuilder.group({
          
            email: ['', [Validators.required, Validators.email]],
          
            firstName: ['', Validators.required],
          
            lastName:['', Validators.required],
          
            address: ['', Validators.required],
          
          })
          

          }

          就是这样。快乐编码

          【讨论】:

          • 问题是添加自定义验证器
          猜你喜欢
          • 2020-01-13
          • 2021-11-01
          • 2019-07-09
          • 2019-03-08
          • 2020-04-06
          • 2019-05-20
          • 1970-01-01
          • 1970-01-01
          • 2019-05-04
          相关资源
          最近更新 更多