角度形式无法通过动态角度形式更新验证

时间:2020-09-03 07:31:36

标签: angular validation angular-forms

我现在遇到一个角度形式的问题,该问题无法以动态角度形式动态更新验证。

在此示例中,有一个选择项,可以选择电子邮件或电话,并且在此选择器下有一个输入字段,可以是电子邮件或电话号码。

但是问题是,如果select的值更改,那么验证子组件将不会更新。

代码如下:


<div *ngFor="let item of contactForm.get('information').controls; let informationIndex = index">
              <div [formGroupName]="informationIndex">
                <div fxLayout="row" class="parameterWrapper">
                  <div class="parameterLabel step">type</div>
                  <label>
                    <select class="parameterInputSelect" formControlName="type" (change)="setContactValidation($event, informationIndex, contactFormIndex)">
                      <option *ngFor="let param of getContactInformationTypes(false)" [value]="param">{{param}}</option>
                    </select>
                  </label>
                </div>
                <div fxLayout="row" class="parameterWrapper">
                  <div class="parameterLabel step">detail</div>
                  <label>
                    <input class="parameterInput" type="text" formControlName="detail" [value]="item.controls.detail">
                  </label>
                  <app-validation-errors type="detail" [control]="item.controls.detail" [selectedValue]="selectedInfoType"></app-validation-errors>
                </div>
              </div>

在此代码中,您可以看到一个选择和一个输入字段。还有一个子组件validate-error。

在ts文件中

public setContactValidation(value: any, infoIndex: number, contactFormIndex: number): void {
    this.selectedInfoType = value.target.value;
    const information = this.contactFormData.controls[contactFormIndex].get('information') as FormArray;
    let validator = [];
    switch (this.selectedInfoType) {
      case ContactInformation.TypeEnum.EMAIL:
        validator = [Validators.email];
        information.controls[infoIndex].get('detail').setValidators(validator);
        break;
      case ContactInformation.TypeEnum.PHONE:
        validator = [Validators.pattern(VALIDATORS.ONLY_NUMBER)];
        information.controls[infoIndex].get('detail').setValidators(validator);
        break;
      default:
        break;
    }
    information.controls[infoIndex].updateValueAndValidity();
  }

但是,如果我选择电子邮件,则输入字段中的验证无效。如果选择值更改,如何更新子组件验证错误。

任何解决方案?

2 个答案:

答案 0 :(得分:0)

您正在设置验证器,但不删除旧的验证器。

无论何时更改为“电子邮件”,都需要在设置“电子邮件验证器”之前删除现有的验证器。希望你明白我的意思。

答案 1 :(得分:0)

我认为问题在于,在运行时添加或删除验证器时,必须调用updateValueAndValidity()才能使新验证生效。

无论如何,我建议创建一个自定义表单验证。取决于两个值,请记住在更改类型时使用form.get('detail')。updateValue

<form [formGroup]="form">
  <select formControlName="type" 
          (change)="form.get('detail').updateValueAndValidity()">
    <option value="email">email</option>
    <option value="phone">phone</option>
    </select>
  <input  formControlName="detail">
  <div *ngIf="form.get('detail').errors">
     {{form.get('detail').errors|json}}
    </div>
  </form>

form=new FormGroup({
    'type':new FormControl('email'),
    detail:new FormControl(null,this.validatorType())

  })

  validatorType()
  {
    return (control:FormControl)=>{
      const form=control.parent?(control.parent as FormGroup):null
      if (form)
      {
        if (form.get('type').value=='email')
          return Validators.email(control)
        else
          return Validators.pattern(/^[0-9]\d*$/)(control)
      }
     
      return null
    }
  }

您可以看到stackblitz