Angular 4 FormGroup removeControl() 不更新表单
Angular 4 FormGroup removeControl() does not update the form
我正在尝试弄清楚如何从反应式表单中删除元素。
这是一个小例子:http://plnkr.co/edit/HyhMDoMtek02CyKpZ7Wt?p=preview
当我点击 X
按钮时,表单对象已更新,但表单 UI 仍然有该项目。
如何让表单在删除时自行更新?
在模板中,您正在迭代小部件
<div *ngFor='let item of widget.items'>
<input type='text' [formControlName]='item.id'>
<button type='button' (click)='deleteItem(item.id)'>X</button>
</div>
所以你需要做的是从小部件中删除表单
deleteItem(id: number){
var elem = this.widget.items.find((i)=>i.id == id);
this.widget.items.splice(this.widget.items.indexOf(elem), 1)
(<FormGroup>this.form).removeControl(id.toString());
}
其他选项不是通过对象迭代而是通过控件对象迭代
<div *ngFor='let control of form.controls'>
<input type='text' [formControl]='control'>
<button type='button' (click)='deleteItem(item.id)'>X</button>
</div>
我公司在使用 FormGroups 在我们基于 angular 的网站上动态添加和删除控件时遇到了这个问题。
我们的软件有一个动态覆盖 added/removed FormControls 的 FormGroup。当您 add/remove widget.items 条目时,控件会从显示的页面获得 added/removed。
任何时候你想添加一个小部件,你首先添加一个新条目到 widget.items 列表然后你添加一个新的表单控件到 FormGroup(使用 FormGroup.addControl)。新控件按预期添加到控件列表的底部,并且与控件关联的任何验证器也将添加到它。所有现有控件都维护其数据和验证器。
另一方面,如果您从 widget.items 列表中除底部以外的任何位置删除控件,而不是删除页面上的相应控件,Angular 会删除底部控件。这将导致现在删除的小部件项目处或下方的所有控件都具有不正确的数据,而现在删除的条目处的项目仍然包含旧信息。
要解决此问题并让 angular 知道它需要正确更新整个表单组,您可以执行以下操作(假设 widget.items = [widget1, widget2, widget3, widget4]) :
- 将widget.items设置为[]
widget.items = []
- 检测变化
this.changeDetectorRef.detectChanges()
- 重置 widget.items 到修改后的列表(也就是没有要删除的项目的列表)
widget.items = [widget1, widget3, widget 4]
这将导致页面列表被刷新,并包含有效数据和工作验证器。
对于我们的软件,这是必需的,因为它处理自定义控件并连接 FormGroup/FormControl 创建和生命周期的方式。希望这对遇到类似情况的人有所帮助,但在您尝试此解决方案之前,请尝试接受的答案中的策略,因为这是一种更简洁的方法。
我正在尝试弄清楚如何从反应式表单中删除元素。
这是一个小例子:http://plnkr.co/edit/HyhMDoMtek02CyKpZ7Wt?p=preview
当我点击 X
按钮时,表单对象已更新,但表单 UI 仍然有该项目。
如何让表单在删除时自行更新?
在模板中,您正在迭代小部件
<div *ngFor='let item of widget.items'>
<input type='text' [formControlName]='item.id'>
<button type='button' (click)='deleteItem(item.id)'>X</button>
</div>
所以你需要做的是从小部件中删除表单
deleteItem(id: number){
var elem = this.widget.items.find((i)=>i.id == id);
this.widget.items.splice(this.widget.items.indexOf(elem), 1)
(<FormGroup>this.form).removeControl(id.toString());
}
其他选项不是通过对象迭代而是通过控件对象迭代
<div *ngFor='let control of form.controls'>
<input type='text' [formControl]='control'>
<button type='button' (click)='deleteItem(item.id)'>X</button>
</div>
我公司在使用 FormGroups 在我们基于 angular 的网站上动态添加和删除控件时遇到了这个问题。
我们的软件有一个动态覆盖 added/removed FormControls 的 FormGroup。当您 add/remove widget.items 条目时,控件会从显示的页面获得 added/removed。
任何时候你想添加一个小部件,你首先添加一个新条目到 widget.items 列表然后你添加一个新的表单控件到 FormGroup(使用 FormGroup.addControl)。新控件按预期添加到控件列表的底部,并且与控件关联的任何验证器也将添加到它。所有现有控件都维护其数据和验证器。
另一方面,如果您从 widget.items 列表中除底部以外的任何位置删除控件,而不是删除页面上的相应控件,Angular 会删除底部控件。这将导致现在删除的小部件项目处或下方的所有控件都具有不正确的数据,而现在删除的条目处的项目仍然包含旧信息。
要解决此问题并让 angular 知道它需要正确更新整个表单组,您可以执行以下操作(假设 widget.items = [widget1, widget2, widget3, widget4]) :
- 将widget.items设置为[]
widget.items = []
- 检测变化
this.changeDetectorRef.detectChanges()
- 重置 widget.items 到修改后的列表(也就是没有要删除的项目的列表)
widget.items = [widget1, widget3, widget 4]
这将导致页面列表被刷新,并包含有效数据和工作验证器。
对于我们的软件,这是必需的,因为它处理自定义控件并连接 FormGroup/FormControl 创建和生命周期的方式。希望这对遇到类似情况的人有所帮助,但在您尝试此解决方案之前,请尝试接受的答案中的策略,因为这是一种更简洁的方法。