如何使用验证编辑嵌套的反应式表单?

Posted

技术标签:

【中文标题】如何使用验证编辑嵌套的反应式表单?【英文标题】:How to edit nested reactive form with validation? 【发布时间】:2019-07-18 19:31:40 【问题描述】:

我正在从具有数组数据格式的服务中检索数据。现在,如果我有 n 个数据的数组,我如何以嵌套形式绑定数据?表单已经填满了这些数据,并且验证字段也应用在其中。

这是我的父组件html代码。

<form [formGroup]="secondForm" (ngSubmit)="onSecondSubmit()" *ngIf="EnableSecond" [hidden]="!myForm.valid">

            <div formArrayName="items">

                <div *ngFor="let address of secondForm.get('items')['controls']; let i=index">


                    <div>
                        <label>Email Template - i + 1</label>
                        <span *ngIf="secondForm.controls.items.controls.length > 1" (click)="removeAddress(i)"> Remove
                        </span>
                    </div>
                    <editworkflow [groups]="secondForm.controls.items.controls[i]"></editworkflow>
                </div>
            </div>
            <a (click)="addAddress()">
                Create More Email Template
            </a>
            <div>
                <div>

                    <button nbButton type="submit" [disabled]="!secondForm.valid">Confirm</button>
                </div>
            </div>
        </form>

这是父组件打字稿文件。

ngOnint()
this.usermodel.items =   this.items /*my array of object which i am getting 
from services*/ 
this.secondForm = this._fb.group(
        items: this._fb.array([
            this.initAddress(),
        ])
    );

initAddress() 
    return this._fb.group(
        EmailType: [this.usermodel.items.name, Validators.required],
        name: [this.usermodel.items.name, Validators.required],
        subject: [this.usermodel.items.template.subject, Validators.required],
        'from': [this.usermodel.items.template.from, [Validators.required, ValidationService.emailValidator]],
        'body': [this.usermodel.items.template.body, [Validators.required]],
        'active': [],
        'confidential': [],
        'numberOfDaysToWait': ['', Validators.required],
        'sequentialOrder': ['', Validators.required]
    );



addAddress() 
    // add address to the list

    const control = <FormArray>this.secondForm.controls['items'];
    control.push(this.initAddress());


removeAddress(i: number) 
    // remove address from the list
    const control = <FormArray>this.secondForm.controls['items'];
    control.removeAt(i);

我的对象数组将如下所示。

   "items": [
    
      "template": 
        "name": "Series 1 email",
        "from": "TEAMGMG",
        "subject": "GROUP2 - SERIES1 - EMAIL",
        "body": "<html><body><strong>My test email</strong></body></html>",
        "confidential": true,
        "active": true
      ,
      "sequentialOrder": 1,
      "numberOfDaysToWait": 0,
      "name": "Test email sequence 1",
      "description": "Test email GROUP 2 sequence 1 - description"
    , 
      "template": 
        "name": "Series 2 email",
        "from": "TEAMGMG",
        "subject": "GROUP2 - SERIES2 - EMAIL",
        "body": "<html><body><strong>My test email2</strong></body></html>",
        "confidential": true,
        "active": true
      ,
      "sequentialOrder": 2,
      "numberOfDaysToWait": 10,
      "name": "Test email sequence 2",
      "description": "Test email sequence 2 - description"
    
  ]
]

【问题讨论】:

您是否收到任何错误消息? 没有。我没有办法绑定元素或如何在 html 中传递我的值? 我正在这个变量中获取数据,它是对象数组 this.userModel.items 。现在我如何将此模型传递给 ngfor 循环。一个循环已经用于表单控制 您能否进一步解释您的问题是什么?我不太明白。你是说“表单已经填满了这些数据,并且验证字段也被应用在其中。” 我在您的代码中没有看到“userModels” 【参考方案1】:

您可以创建一个接收“数据”或 null 的函数并返回一个 FormGroup

  addAddress(data:any) 
    //if received a null, create a data with the necesary properties
    data=data||template:from:'',:'',name:'',subject:'',...,sequentialOrder:0,...
    return this._fb.group(
        EmailType: [data.template.from, Validators.required],
        name: [data.template.name, Validators.required],
        subject: [data.template.subject, Validators.required],
        'from': [data.template.from, [Validators.required, ValidationService.emailValidator]],
        'body': [data.template.body, [Validators.required]],
        'active': [data.template.active],
        'confidential': [data.template.confidential],
        'numberOfDaysToWait': [data.numberOfDaysToWait, Validators.required],
        'sequentialOrder': [data.sequentialOrder, Validators.required]
    );
 

因此,您可以使用

添加到数组中
control.push(this.addAddress(null));
//or
control.push(this.addAddress(data));

你可以在 ngOnInit 上使用

this.usermodel.items =   this.items
this.secondForm = this._fb.group(
        items: this._fb.array(items.map(data=>this.addAddress(data))
    );

items.map,将你的item数组转换成formGroup数组

【讨论】:

您创建的数据。此数据将在 this.usermodel.items 中。我可以全局访问并检查我的 addAddress() 函数,我已经在推送数据。但是我如何在循环中使用它。假设我将用我的 this.userModel.items.name 替换您的 data.template.from。那么它会解决问题吗? 我在哪里调用这个地址()函数? 当你有你可以做的对象数组时,例如const control=this.secondForm.controls['items'];control=item.forEach(x=>control.push(this.addAddress(x)) 检查我编辑的问题格式。这就是你要我做的。但是如何在我的子组件中传递这些数据? 我希望我的表单预先填写此值。

以上是关于如何使用验证编辑嵌套的反应式表单?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用反应表单挂钩验证反应日期选择器

如何在反应中验证多步表单

反应表单钩子如何验证选择选项

Mat Table 中的嵌套反应表单找不到控件

您如何在 Node.js + Express + Mongoose + Jade 中处理表单验证,尤其是嵌套模型

如何在角度 2 中以反应形式重置验证器?