使用FormBuilder的角反应形式自定义验证

时间:2018-08-21 17:40:38

标签: angular angular-reactive-forms

我有一个名为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是否存在某些使自定义验证器不可用的事情?

5 个答案:

答案 0 :(得分:3)

有关更多信息---> 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;
            }
        }
}

答案 1 :(得分:3)

尝试使用验证器代替自定义验证器的验证器 文档:https://angular.io/api/forms/AbstractControl#root

  

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

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

答案 2 :(得分:1)

当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>

答案 3 :(得分:0)

如果您要使用组验证方法,请尝试使用

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

答案 4 :(得分:0)

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

在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],

})

}

就是这样。编码愉快