反应式表单数组 - 推送新元素时避免验证错误 [英] Reactive Form Array - Avoid Validation Error when push new elements

查看:21
本文介绍了反应式表单数组 - 推送新元素时避免验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由单个表单数组组成的表单组:

ngOnInit() {this.deviceDetailsFormGroup = this._formBuilder.group({设备详细信息:this._formBuilder.array([this.buildDeviceDetailsForm()])});}

表单数组中的每个控件都需要验证器:

buildDeviceDetailsForm(): FormGroup {返回 this._formBuilder.group({ipAddressCtrl: [",[Validators.pattern(ipaddressPattern), Validators.required]],主机名Ctrl: [",[Validators.required,Validators.maxLength(30),Validators.minLength(5)]]});}

以下是我对表单数组的推送和删除功能:

addNewDevice() {this.deviceItems = this.deviceDetailsFormGroup.get(设备详细信息") 作为 FormArray;如果(this.deviceItems.length > MAX_DEVICES){this.toastNotif.errorToastNotif(`单个作业扫描最多可以选择 ${MAX_DEVICES} 个设备`,选择的设备太多");返回;}如果(this.deviceDetailsFormGroup.invalid){返回;}let mapIP = new Map();//警告表单中的重复 IPthis.deviceItems.controls.forEach(ctrl => {如果(mapIP[ctrl.value.ipAddressCtrl] === 0){this.toastNotif.warningToastNotif(您在表单字段中输入了重复的 IP",复制"+ "知识产权");}mapIP[ctrl.value.ipAddressCtrl] = 0;});this.deviceItems.push(this.buildDeviceDetailsForm());}移除设备(我:数字){this.deviceItems.removeAt(this.deviceItems.length - 1);}

当我将新元素推送到 Form Array 时,它们被标记为无效,尽管它们未受影响且原始.我知道这是由创建新的 FormGroup 时设置的验证器和空默认值引起的.

是否可以避免这种行为,以便 FormArray 元素仅在被触摸时才被标记为错误?

提前致谢.

解决方案

Luca,FormArray 中的formControl 会一直无效,所以FormArray 无效,表单无效.您需要检查是否触摸了控件.this stackblitz 中的一个简单示例.你看,如果你添加,控件无效,但没有触及

.html 是一种典型的形式

<form [formGroup]="myForm"><div formArrayName="myFormArray"><div *ngFor="let group of myFormArray.controls;let i=index" [formGroupName]="i"><input formControlName="name"><!--仅在触摸后显示且无效--><div *ngIf="group.get('name').touched && group.get('name').invalid">无效和被触动

<!--在向数组添加新表单组时始终显示--><div *ngIf="group.get('name').invalid">无效的

</表单>

.ts 是经典"

myForm=new FormGroup({myFormArray:new FormArray([])})获取 myFormArray(){返回 this.myForm.get('myFormArray') 作为 FormArray}创建组(){返回新的表单组({名称:新 FormControl('',Validators.required)})}添加(){this.myFormArray.push(this.createGroup())}

I have a form group which is composed by a single form array:

ngOnInit() {
    this.deviceDetailsFormGroup = this._formBuilder.group({
        deviceDetails: this._formBuilder.array([
            this.buildDeviceDetailsForm()
        ])
    });
}

Each control in the Form Array has required validators:

buildDeviceDetailsForm(): FormGroup {
    return this._formBuilder.group({
        ipAddressCtrl: [
            "",
            [Validators.pattern(ipaddressPattern), Validators.required]
        ],
        hostnameCtrl: [
            "",
            [
                Validators.required,
                Validators.maxLength(30),
                Validators.minLength(5)
            ]
        ]
    });
}

Below are my push and remove functions to the Form Array:

addNewDevice() {
    this.deviceItems = this.deviceDetailsFormGroup.get(
        "deviceDetails"
    ) as FormArray;

    if (this.deviceItems.length > MAX_DEVICES) {
        this.toastNotif.errorToastNotif(
            `A maximum of ${MAX_DEVICES} devices can be selected for a single job scan`,
            "Too many devices selected"
        );
        return;
    }

    if (this.deviceDetailsFormGroup.invalid) {
        return;
    }

    let mapIP = new Map<string, number>();

    // Warn about duplicate IP's in form
    this.deviceItems.controls.forEach(ctrl => {
        if (mapIP[ctrl.value.ipAddressCtrl] === 0) {
            this.toastNotif.warningToastNotif(
                "You have entered duplicate IP's in the form fields",
                "Duplicate" + " IP's"
            );
        }

        mapIP[ctrl.value.ipAddressCtrl] = 0;
    });

    this.deviceItems.push(this.buildDeviceDetailsForm());
}

removeDevice(i: number) {
    this.deviceItems.removeAt(this.deviceItems.length - 1);
}

When I push new elements to the Form Array, they're marked as invalid although they're untouched and pristine. I understand that's caused by the Validators and empty default values set when I create the new FormGroup.

Is it possible to avoid this behavior so the FormArray elements are marked as errors only if they're touched ?

Thanks in advance.

解决方案

Luca, the formControl in the FormArray will be invalid always, so the FormArray is invalid and the form is invalid. You need check if the control is touched. A simple example in this stackblitz. You see that if you add, the control is invalid, but not touched

The .html is a tipical form

<button (click)="add()">Add</button>
<form [formGroup]="myForm">
<div formArrayName="myFormArray">
  <div *ngFor="let group of myFormArray.controls;let i=index" [formGroupName]="i">
       <input formControlName="name">
       <!--show only after touched and invalid-->
       <div *ngIf="group.get('name').touched && group.get('name').invalid">
         invalid and touched
       </div>
       <!--show always when add a new formGroup to array-->
       <div *ngIf="group.get('name').invalid">
         invalid 
       </div>
  </div>
  </div>
  </form>

And the .ts a "clasic"

myForm=new FormGroup({
     myFormArray:new FormArray([])
  })

  get myFormArray()
  {
    return this.myForm.get('myFormArray') as FormArray
  }
  createGroup()
  {
    return new FormGroup({
      name:new FormControl('',Validators.required)
    })
  }
  add()
  {
    this.myFormArray.push(this.createGroup())
  }

这篇关于反应式表单数组 - 推送新元素时避免验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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