*ngFor 动态创建的表单组件在表单控件中保持价值

Posted

技术标签:

【中文标题】*ngFor 动态创建的表单组件在表单控件中保持价值【英文标题】:Dynamically created form component by *ngFor is keeping value in form controls 【发布时间】:2020-01-02 10:45:58 【问题描述】:

我正在尝试在 mat-expansion-panel 中动态生成表单(以及提供整个上下文的对话框)。现在,我成功地使用 *ngFor 循环生成了新的扩展面板和里面的表单。问题来自两点:

扩展面板内的表单来自我编写的组件 用户负责通过单击“添加”按钮生成新的扩展面板和内部表单

最终的结果是一切都按预期工作,但是如果用户开始在第一个表单中填写一些信息并决定在手风琴中创建一个新表单,则新创建的表单将使用以下数据填充其表单控件以前的重点形式:(

这是一个代码示例

父手风琴

(...)
<mat-step>            
    <ng-template matStepLabel>Ajouter des appartements</ng-template>           
    <button mat-raised-button (click)="addApartment()">Add</button>
    <mat-accordion multi="true">
        <mat-expansion-panel *ngFor="let apartment of apartments">
             <mat-expansion-panel-header>
                  <mat-panel-title>
                       apartment.title
                  </mat-panel-title>
                  <mat-panel-description>
                       apartment.description
                  </mat-panel-description>                
             </mat-expansion-panel-header>                
             <app-add-apartment-form [parentForm]="addLocationForm"></app-add-apartment-form>            
        </mat-expansion-panel>    
    </mat-accordion>            
</mat-step>
(...)

.ts 文件

(...)
addApartment()
    this.apartments.push(new Apartment());
  
(...)

子组件表单(没什么花哨的)


<div [formGroup]="parentForm">
    <p>
        <mat-form-field formGroupName="apartmentDetails"> 
            <input matInput placeholder="Titre" formControlName="title" >
            <mat-error *ngIf="f.title.invalid">getTitleErrorMessage()</mat-error>
        </mat-form-field>
    </p>
    <p>
        <mat-form-field formGroupName="apartmentDetails">
            <textarea matInput placeholder="Description" formControlName="description" ></textarea>
            <mat-error *ngIf="f.description.invalid">getDescriptionErrorMessage()</mat-error>
        </mat-form-field>
    </p>
    <p>
        <mat-form-field formGroupName="apartmentDetails">
            <mat-label>Etage</mat-label>
            <mat-select  formControlName="floor">
                <mat-option *ngFor="let floor of floors" [value]="floor.value">
                    floor.viewValue
                </mat-option>
            </mat-select>            
            <mat-error *ngIf="f.floor.invalid">getFloorErrorMessage()</mat-error>
        </mat-form-field>
    </p>
(...)

这是结果图片:

第一个表单填写https://i.imgur.com/4sfkWhE.png

添加第二种形式https://i.imgur.com/NL8X9h7.png

感谢您的帮助!

【问题讨论】:

1.-创建 formGroups 的表单数组,2.-循环 formArray 控件,3.-将 formArray.at(index) 传递给您的组件(或者如果迭代 *ngFor=" grp of myArray.controls",简单地使用 grp 来喂你的子组件。) 好的,谢谢。所以我需要在我的子组件中动态生成表单控件。你能解释一下为什么我不能使用我的子组件的 html 文件模板吗?为什么 ngfor 会重复值? 查看我的回答 - 我相信这不是必需的,所以请按照您的代码输入 - 【参考方案1】:

稍微改变一下你的表格,但简而言之,完成我的评论的元素是:

<form *ngIf="form" [formGroup]="form">
<mat-accordion>
  <mat-expansion-panel *ngFor="let grp of form.controls;let i=index" [formGroup]="grp">
    <mat-expansion-panel-header>
      <mat-panel-title>
 <mat-panel-title>
                       grp.get('title').value
                  </mat-panel-title>
                  <mat-panel-description>
                       grp.get('description').value
                  </mat-panel-description> 
      </mat-panel-title>
    </mat-expansion-panel-header>
    <app-add-apartment-form [parentForm]="grp"></app-add-apartment-form>
  </mat-expansion-panel>
</mat-accordion>
</form>

你的表格是

form=new FormArray([])

你有一个功能

createGroup()

   return new FormGroup(
     title:new FormControl()
     description:new FormControl()
     floor:new FormControl() 
   )

还有你的孩子

<div [formGroup]="parentForm">
<input formControlName="title">
<input formControlName="description">
<input formControlName="floor">
</div>

你有一个函数 add 是

add()

  this.form.push(this.createGroup())

【讨论】:

谢谢。让我试一试,我会回到你身边。 谢谢。它就像一个魅力。我修改了一些你的代码,但这很完美!再次感谢您。

以上是关于*ngFor 动态创建的表单组件在表单控件中保持价值的主要内容,如果未能解决你的问题,请参考以下文章

Angular2:输入控制带有ngFor的表单标签内的损失值

带有 ngFor 输入的 Angular 2 模板驱动表单

使用 ngFor 在表单内动态设置离子输入值

使用 *ngFor 并从中提交值的动态表单

选择表单控件在 Angular 7 中返回 [object Object]

在 Angular2 中动态创建输入表单