首页 > 解决方案 > Angular 10 动态嵌套表单输出到 html 表

问题描述

我有一个使用 FormArray 的动态嵌套表单的 Angular 表单。我从另一篇文章中得到了嵌套表单的想法。我正在尝试将嵌套表单输出到具有行跨度的 html 表。我认为我的结构已正确计算,但是当我尝试将嵌套表单呈现到表格时,标题被推到右侧,第一列成为整个输出的列。

我在这里有一个 stackblitz 条目: https ://stackblitz.com/edit/angular-ivy-4zjniz?file=src/app/app.component.ts

当表单首次呈现时,它会显示: First time on component image

然后,当我单击 Add Seat Emp 和 Add Skill 时,标题会像这样被推过去。

添加了父子图像

如何让标题保持在左侧并为表格正确呈现?先感谢您。

这是我的html代码:(app.component.html)

<div class="control-section e-rte-custom-tbar-section">
  <div >
    <form [formGroup]="empForm" (ngSubmit)="onSubmit()">
      <div formArrayName="employees">
        <table>
          <tr>
            <th rowspan="{rowSpan}">Emp #</th>
            <th rowspan="{rowSpan}">First</th>
            <th rowspan="{rowSpan}">Last</th>
            <th rowspan="{rowSpan}">Remove Emp Action</th>
            <th>Skill #</th>
            <th>Skill</th>
            <th>Exp</th>
            <th>Remove Skill Action</th>
          </tr>

          <ng-container *ngFor="let employee of employees().controls; let empIndex=index">  
            <tr [formGroupName]="empIndex">
              <td>{{empIndex}}</td>
              <td><input type="text" formControlName="firstName" placeholder="first"></td>
              <td><input type="text" formControlName="lastName" placeholder="last"></td>
              <td><button (click)="removeEmployee(empIndex)">Remove Emp</button></td>

              <div formArrayName="skills">
                <ng-container *ngFor="let skill of employeeSkills(empIndex).controls; let skillIndex=index">
                  <div [formGroupName]="skillIndex">
                    <tr>
                      <td>{{skillIndex}}</td>
                      <td><input type="text" formControlName="skill" placeholder="skill"></td>
                      <td><input type="text" formControlName="exp" placeholder="exp"></td>
                      <td><button (click)="removeEmployeeSkill(empIndex,skillIndex)">Remove Skill</button></td>
                    </tr>
                  </div>
                </ng-container>
                <tr><button type="button" (click)="addEmployeeSkill(empIndex)">Add Skill</button></tr>
              </div>
            </tr>
          </ng-container>
        </table>
      </div>
    
      <p>
        <button type="button" (click)="addEmployee()">Add Seat Emp</button>
      </p>
      <p>
        <button type="submit">Submit</button>
      </p>
    
    </form>
    
  </div>
</div>

这是代码:(app.component.ts)

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular ' + VERSION.major;

  title = 'Nested FormArray Example Add Form Fields Dynamically';

  empForm:FormGroup;


  constructor(private fb:FormBuilder) {

    this.empForm=this.fb.group({
      employees: this.fb.array([]) ,
    })
  }


  employees(): FormArray {
    return this.empForm.get("employees") as FormArray
  }


  newEmployee(): FormGroup {
    return this.fb.group({
      firstName: '',
      lastName: '',
      skills:this.fb.array([])
    })
  }


  addEmployee() {
    console.log("Adding a employee");
    this.employees().push(this.newEmployee());
  }


  removeEmployee(empIndex:number) {
    this.employees().removeAt(empIndex);
  }


  employeeSkills(empIndex:number) : FormArray {
    return this.employees().at(empIndex).get("skills") as FormArray
  }

  newSkill(): FormGroup {
    return this.fb.group({
      skill: '',
      exp: '',
    })
  }

  addEmployeeSkill(empIndex:number) {
    this.employeeSkills(empIndex).push(this.newSkill());
  }

  removeEmployeeSkill(empIndex:number,skillIndex:number) {
    this.employeeSkills(empIndex).removeAt(skillIndex);
  }

  onSubmit() {
    console.log(this.empForm.value);
  }


}


export class country {
  id: string;
  name: string;

  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }
}

标签: angularhtml-tablenestedformarray

解决方案


这一行:

<div *ngFor="let employee of employees().controls; let empIndex=index">

弄乱了表格的标记,因为它添加了一个额外的div.

您可以将其更改为:

<ng-container *ngFor="let employee of employees().controls; let empIndex=index"> 

然后div不会添加额外的。我在您的 Stackblitz 中尝试了这一点,现在似乎可以通过这种更改正常工作。

在此处输入图像描述

ngContainerAngular 文档中阅读更多 Angular 的内容。

在结构的更深处,还有另一个问题来自div嵌套在表格中的更多元素。您可以将它们全部替换为ngContainer,它也适用于formArrayNameformGroupName。但是还有一个tr元素内嵌套元素的另一个问题tr。对于表格,嵌套divstr元素都是无效的 HTML。

全部替换为并删除嵌套元素后divngContainertr遇到了另一个问题。

在此处输入图像描述

所以现在我认为你可能需要重新考虑一下解决方案。一个快速的想法可能是为技能行添加一个嵌套表。现在看起来像这样: 在此处输入图像描述

也许它看起来不像你想要的那样,但它现在至少是一个有效的 HTML 表格,如果你改变员工数据单元格的对齐方式,也许一些 CSS 可以使它看起来更好。但我认为不可能有一张表在同一张表中显示所有员工及其技能,我认为您需要像我的示例中那样使用嵌套表,或者为此考虑不同的解决方案。

我已经分叉了您的 Stackblitz 并在此处添加了嵌套表。


推荐阅读