角度反应形式根据另一个字段的值有条件地验证字段

问题描述 投票:0回答:3

这是我的代码

detailsGroup = new FormGroup({
    userId:new FormControl('1'),
    firstName: new FormControl('', Validators.required),
    lastName: new FormControl('', Validators.required),
    email: new FormControl('',[ Validators.required, Validators.email]),
  });

我想要如果

userId equal to 1
那么名字姓氏和电子邮件不需要
otherwise
这 3 个字段更改为必填字段,并且电子邮件还会验证电子邮件地址。

谢谢

angular angular-reactive-forms angular-validation
3个回答
4
投票

您应该编写一个自定义验证器,如下所示: 演示:https://angular-custom-validator-p2u1jv.stackblitz.io

function nameValidator(form: FormGroup): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const needRequire = form.get('userId').value != 1
    const noValue = needRequire ? !(control.value) : false
    return noValue ? {required: control.value} : null;
  };
}
this.form = new FormGroup({
  userId:new FormControl('1'),
  firstName: new FormControl(''),
  lastName: new FormControl(''),
  email: new FormControl('',[ Validators.required, Validators.email]),
});

this.form.get('firstName').setValidators(nameValidator(this.form))
this.form.get('lastName').setValidators(nameValidator(this.form))

0
投票

为了实现此目的,您可以使用

setValidators
提供的 clearValidtors
FormControl
方法。下面介绍了如何使用它们从表单的特定控件中动态添加或删除验证器。此外
setValidators
方法采用单个验证器或验证器数组作为参数,因此在电子邮件的情况下,您可以像这样使用它

this.detailsForm.get('email').setValidators([Validators.required,Validators.email]);

由于 Angular 提供了必需的验证器和电子邮件验证器,因此您无需编写任何自定义验证器函数。

import { Component, OnInit, VERSION } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;
  detailsForm: FormGroup;
  validation: boolean;
  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.detailsForm = this.formBuilder.group({
      userId: ['', [Validators.required]],
      firstName: ['', [Validators.required]],
      lastName: ['', [Validators.required]],
      email: ['', [Validators.required]],
    });
    this.detailsForm.get('userId').valueChanges.subscribe(() => {
      const val = this.detailsForm.getRawValue();
      if (val.userId.toString() === '1') {
        Object.keys(this.detailsForm.controls).forEach((controlName) => {
          this.detailsForm.controls[controlName].clearValidators();
          this.detailsForm.controls[controlName].updateValueAndValidity();
        });
      } else {
        Object.keys(this.detailsForm.controls).forEach((controlName) => {
          this.detailsForm.controls[controlName].setValidators(
            Validators.required
          );
          this.detailsForm.controls[controlName].updateValueAndValidity();
        });
      }
      this.validation = this.detailsForm.get('email').valid;
    });
  }
}

这里有一个“工作演示”。如果您输入 1 封电子邮件,则没有验证器并且被认为是有效的。如果您输入任何其他值,电子邮件控件将变得无效。 您可以在此处使用上面的

可编辑代码


0
投票

private _buildForm(): void { this.storeForm = this._fb.group({ name: [ '', Validators.compose([ Validators.required, Validators.minLength(3) ]) ], doesContainDemo: [true], sectorId: ['', this._sectorValidator()], }); }

SectorValidator 如下

private _sectorValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } | null => { const doesContainDemo = this.storeForm?.controls['doesContainDemo'].value; const storeSector = this.storeForm?.controls['sectorId'].value; if (doesContainDemo === true && !storeSector) { return { conditionalRequired: true }; } return null; }; }

© www.soinside.com 2019 - 2024. All rights reserved.