Angular 10动态嵌套表单输出到html表

问题描述

我有一个Angular表单,并且使用FormArray具有动态嵌套表单。我从另一个帖子中得到了嵌套表格的想法。我正在尝试将嵌套的表单输出到具有rowpan的html表中。我认为我已经正确地构造了结构,但是当我尝试将嵌套表单呈现到表时,标题被推到右侧,并且第一列成为整个输出的列。

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

第一次呈现表单时,它显示以下内容First time on component image

然后,当我单击“添加座椅Emp”和“添加技能”时,标题将被推倒。

Added parent and child image

如何使标题保持在左侧并正确显示表格?预先谢谢你。

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

@H_502_14@<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)

@H_502_14@ 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; } }

解决方法

此行:

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

弄乱了表格的标记,因为它增加了额外的div

您可以将其更改为此:

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

,则不会添加多余的div。我在您的Stackblitz中进行了尝试,现在通过该更改似乎可以正常工作。

enter image description here

Angular docs中阅读更多Angular的ngContainer

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

div替换所有ngContainer并删除嵌套的tr元素后,您还有另一个问题。

enter image description here

所以现在我认为您可能需要重新考虑一下解决方案。一个快速的想法可能是为技能行添加一个嵌套表。现在看起来像这样: enter image description here

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

我已经分叉了您的Stackblitz,并添加了嵌套表here