Angular 6 - 多级嵌套反应式表单复制输入



我有一个与角反应形式相关的问题,我无法解决。

法典

form.htmlform.ts

import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup} from '@angular/forms';
import {ProcessService} from "../../../service/process.service";
@Component({
selector: 'app-check-order-form',
templateUrl: './check-order-form.component.html',
styleUrls: ['./check-order-form.component.css']
})
export class CheckOrderFormComponent implements OnInit {
submitted = false;
X: FormGroup = this._fb.group({
field: '',
Y: this._fb.array([])
});
Yg: FormGroup = this._fb.group({
subfield: '',
Z: this._fb.array([])
});
Zg: FormGroup = this._fb.group({
subsubfield: ''
});
constructor(private _fb: FormBuilder) {
}
ngOnInit() {
this.createYg();
this.createZg();
}
ngOnChanges() {
}
onSubmit(formValue) {
this.submitted = true;
console.warn(this.X.value);
}
createYg() {
return this.Yg;
}
createZg() {
return this.Zg;
}

get Y(): FormArray {
return this.X.get('Y') as FormArray;
}
getCurrentZ(index): FormArray {
return this.Y.at(index).get('Z') as FormArray;
}

addY(): void {
this.Y.push(this.createYg());
}
addZ(index): void {
let Z = this.Y.at(index).get('Z') as FormArray;
Z.push(this.createZg());
}
deleteY(index) {
this.Y.removeAt(index);
}
deleteZ(Yindex, index) {
this.getcurrentZ(Yindex).removeAt(index);
}
}
<form class="form-inline" [formGroup]="X" (ngSubmit)="onSubmit(X.value)">

<div class="form-group col-3 mb-2">
<label for="field">Field</label>
<input type="text" class="form-control" formControlName="field" id="field">
</div>
<div class="form-inline" formArrayName="Y">
<div *ngFor="let y of Y?.controls; let k=index">
<hr/>
<div [formGroupName]="k" class="row pt-1 pb-1">
<div class="col-12">
<label>Y {{k + 1}}</label>
</div>
<div class="form-group col-3 mb-2">
<input type="text" class="form-control" formControlName="subfield" placeholder="subfield">
</div>
<div class="form-inline" formArrayName="Z">
<div *ngFor="let fondo of getCurrentZ(k)?.controls; let j=index">
<hr class="bg-secondary"/>
<div [formGroupName]="j" class="pt-1 pb-1">
<label>Z {{j + 1}}</label>
<div class="form-group col-3 mb-2">
<input type="text" class="form-control" formControlName="subsubfield" placeholder="subsubfield">
</div>        
<div class="form-group col-3 mb-2">
<button (click)="deleteZ(k, j)" class="btn btn-danger mr-1">Remove</button>
</div>
</div>
</div>
</div>        
<div class="form-group col-12 mb-2 pr-1">
<button class="btn btn-info mr-1" (click)="addZ(k)">+ Z</button>
</div>
<div class="form-group col-12 mb-2 pr-1">
<button (click)="deleteY(k)" class="btn btn-danger mr-1">
Remove
</button>
</div>
</div>
</div>
</div>
<div class="form-group col-12 mt-2">
<button type="submit" class="btn btn-primary mr-2">Submit</button>
<button (click)="addY()" class="btn btn-success">+ Y</button>
</div>
</form>

问题

以下是导致问题的步骤(请查看上面的代码(:

  1. 我单击+ Y按钮以添加 Y 表单组
  2. 我又点击了一次+ Y
  3. 我单击两个 Y 表单组之一的+ Z

结果:Z 窗体组在两个 Y 元素上呈现。

对我来说,理想的情况是每个 FormGroup 仅与父窗体组相关,以便正确编译表单。我尝试了许多解决方案,但尽管指定了父数组 (Y( 的索引,但我找不到问题。

提前谢谢你。

当您添加Y表单(和Z表单(时,您不会创建新对象,而是一次又一次地使用相同的对象(YgZg(。因此,当您在Y窗体上添加"新"Z时,每个Y窗体都会受到影响,因为它们是相同的。

删除YgZg,并将createYg()createZg()替换为以下内容:

createYg() {
return this._fb.group({
subfield: '',
Z: this._fb.array([])
});
}
createZg() {
return this._fb.group({
subsubfield: ''
});
}

请检查代码,我在 https://angular-4dt3sa.stackblitz.io 中添加了工作模块或代码 https://stackblitz.com/edit/angular-4dt3sa?file=src%2Fapp%2Fapp.component.ts

目录

<form class="form-inline" [formGroup]="X" (ngSubmit)="onSubmit(X.value)">
<div class="form-group col-3 mb-2">
<label for="field">Field</label>
<input type="text" class="form-control" formControlName="field" id="field">
</div>
<div class="form-inline" formArrayName="Y">
<div *ngFor="let y of Y?.controls; let k=index">
<hr/>
<div> test {{k}}</div>
<div [formGroupName]="k" class="row pt-1 pb-1">
<div class="col-12">
<label>Y {{k + 1}}</label>
</div>
<div class="form-group col-3 mb-2">
<input type="text" class="form-control" formControlName="subfield" placeholder="subfield">
</div>
<div class="form-inline" formArrayName="Z">
<div *ngFor="let fondo of getCurrentZ(k)?.controls; let j=index">
<hr class="bg-secondary"/>
<div [formGroupName]="j" class="pt-1 pb-1">
<label>Z {{j + 1}}</label>
<div class="form-group col-3 mb-2">
<input type="text" class="form-control" formControlName="subsubfield" placeholder="subsubfield">
</div>        
<div class="form-group col-3 mb-2">
<button (click)="deleteZ(k, j)" class="btn btn-danger mr-1">Remove</button>
</div>
</div>
</div>
</div>        
<div class="form-group col-12 mb-2 pr-1">
<button class="btn btn-info mr-1" (click)="addZ(k)">+ Z</button>
</div>
<div class="form-group col-12 mb-2 pr-1">
<button (click)="deleteY(k)" class="btn btn-danger mr-1">
Remove
</button>
</div>
</div>
</div>
</div>
<div class="form-group col-12 mt-2">
<button type="submit" class="btn btn-primary mr-2">Submit</button>
<button (click)="addY()" class="btn btn-success">+ Y</button>
</div>
</form>

打字稿

import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
submitted = false;
X: FormGroup = this._fb.group({
field: '',
Y: this._fb.array([])
});
Yg: FormGroup = this._fb.group({
subfield: '',
Z: this._fb.array([])
});
Zg: FormGroup = this._fb.group({
subsubfield: ''
});
constructor(private _fb: FormBuilder) {
}
ngOnInit() {
this.createYg();
this.createZg();
}
ngOnChanges() {
}
onSubmit(formValue) {
this.submitted = true;
console.warn(this.X.value);
}
createYg() {
return this._fb.group({
subfield: '',
Z: this._fb.array([])
});
}
createZg() {
return this._fb.group({
subsubfield: ''
});
}

get Y(): FormArray {
return this.X.get('Y') as FormArray;
}
getCurrentZ(index): FormArray {
return this.Y.at(index).get('Z') as FormArray;
}
addY(): void {
this.Y.push(this.createYg());
}
addZ(index): void {
let Z = this.Y.at(index).get('Z') as FormArray;
let Zg = this.createZg();
Z.push(Zg);
}

deleteY(index) {
this.Y.removeAt(index);
}
deleteZ(Yindex, index) {
let Z = this.Y.at(Yindex).get('Z') as FormArray;
Z.removeAt(index);
}
}

正如LP154所提到的。不应创建新对象。@teskin

最新更新