我在这里使用"@angular/cli": "1.2.6"
,"@angular/core": "^4.0.0"
我想做什么
我试图通过功能输入制作产品的反应形式。在表单内部,如果用户单击"添加功能"按钮,一个新的功能列,包括一个选择框" type"会出现。一旦用户点击"删除"在要素列内的按钮,该要素列将被删除。
我遇到了什么问题
问题是当我尝试删除第一个和最后一个功能列之间的功能列时,formControl已成功更新为正确的值。但是,已删除功能列的选择框的UI将传递到即将发布的下一个功能列。
我期望拥有什么
删除目标要素列后,即将发布的要素列的用户界面将显示正确的值。
示例
1.我尝试删除第二个功能列。
2. formControl成功删除了第二个功能。 UI中的第二个功能列已成功删除。但是,第三个要素列会上升,并使用已删除要素的选择框值替换该空格。
我的代码如下:
产品form.component.ts
formDOM;
features = [];
featureTypes = [
{ id: "pros", name: "pros" },
{ id: "cons", name: "cons" }];
ngOnInit() {
this.formDOM = this.formBuilder.group({
// Have other field....
feature: this.formBuilder.array([])
});
}
patchSingleFeature(feature: object): FormGroup {
let returnObject = this.formBuilder.group({
type: (feature && feature['type'])
// some other field also....
});
this.features.push("feature");
return returnObject;
}
addFeature(): void {
let featureControl = <FormArray>this.formDOM.controls['feature'];
featureControl.push(this.patchSingleFeature(new Feature()));
}
removeFeature(x: number): void {
let numberOfFeature = this.features.length;
let featureControl = <FormArray>this.formDOM.controls['feature'];
featureControl.controls.splice(x, 1);
this.features.splice(x, 1);
}
产品form.component.html
<div class="form" [formGroup]="formDOM">
<div class="col-xs-12">Features</div>
<div *ngFor="let feature of features; let x = index; ">
<feature-input [x]="x" [featureTypes]="featureTypes" [form]="formDOM" (clickEvent)="removeFeature($event)"></feature-input>
</div>
<button (click)="addFeature()">Add Feature</button>
</div>
feature-input.component.html
<div class="feature-input" [formGroup]="form">
<div formArrayName="feature">
<div [formGroupName]="x">
<select formControlName="type">
<option value="" disabled>-- Select Feature Type --</option>
<option *ngFor="let type of featureTypes" [value]="type.id">{{ type.name }}</option>
</select>
</div>
</div>
</div>
特征input.component.ts
@Input() form: FormGroup;
@Input() featureTypes: Array<object>;
@Input() x: number;
@Output() clickEvent new EventEmitter<number>();
removeFeature(x) { this.clickEvent.emit(x); }
答案 0 :(得分:1)
我会对您的代码进行一些更改。我会将整个formarray发送到子组件并在那里迭代它。由于JS中的对象是可变的,因此您不需要EventEmitter
,但您可以在子节点中执行删除操作,而不向父节点发送任何内容。
因此,在这种情况下,由于您没有嵌套表单组,请将整个表单传递给子表单:
<feature-input [featureTypes]="featureTypes" [formGroup]="formDOM"></feature-input>
对输入字段进行适当的更改,然后您的子模板将如下所示:
<div [formGroup]="formGroup">
<div class="feature-input" formArrayName="feature">
<div *ngFor="let ctrl of formGroup.controls.feature.controls; let i = index" [formGroupName]="i">
<select formControlName="type">
<option value="" disabled>-- Select Feature Type --</option>
<option *ngFor="let type of featureTypes" [value]="type.id">{{ type.name }}</option>
</select>
<button (click)="removeFeature(i)">Remove</button>
</div>
</div>
</div>
在removeFeature
中,我们只传递表单组的索引并使用函数removeAt
,该函数可用于表单数组:
removeFeature(index) {
this.formGroup.controls.feature.removeAt(index)
}
就是这样!这是一个演示:https://plnkr.co/edit/kZComoNNfsbCjmVnGt1F?p=preview
答案 1 :(得分:0)
您应该直接在 FormArray 上使用带有索引的 removeAt。
(<FormArray>this.myForm.controls['items']).removeAt(index);
如果您在表单控件上使用 splice,那么您必须对每个项目使用 updateValueAndValidity,然后它将更新数组。
this.formControls.splice(index, 1)
this.formControls.map(data => {data[controls].value.updateValueAndValidity({ onlySelf: false, emitEvent: false });});