我正在尝试构建一个与FormGroup和FormArray兼容的数据表 . 我将使用parentForm组将 Headers 详细信息和行传递给此组件 .
我创建了一个小的添加按钮,点击它,我会动态添加新项目 . 在这种情况下,UI正在更新,但如果我打印formGroup.value(),我只获得传递的初始值 . 不是更新的formControl . 我不确定我错过了什么 .
export class FormTableComponent implements OnChanges {
@Input() headers: Array<string>;
@Input() rows: Array<any>;
@Input() parentFG: FormGroup;
@Input() entriesName: string;
get entries(): FormArray {
return <FormArray>this.parentFG.get(this.entriesName);
}
constructor(private fb: FormBuilder, private cd: ChangeDetectorRef) {}
ngOnChanges() {
this.createFormControls();
}
createFormControls() {
this.parentFG.controls[this.entriesName] = this.fb.array([]);
this.rows.forEach(row => {
this.entries.controls.push(this.fb.group(row));
});
}
}
DEMO
2 回答
您有几个问题:1 . 您将新行推送到FormArray控件以外的FormArray本身
应该
2.不要每次都创建新的FormArray并在调用
createFormControls()
时重新加载每一行,你可以通过get entries()
方法访问它解决方案1:
检查
entries
的长度,如果为0,则用rows
初始化它,否则只需将最后一行按入现有的FormArray
解决方案2:
就个人而言,我更喜欢将
createFormArray()
和appendTo()
或popFrom()
放入父组件中 . 它干净,易读 . 在这种情况下,我们不需要ChangeDetectionRef
.我已将
createFormControls()
从form-table
组件移动到dummy
组件并将其重命名为createFormArray()
并稍微更改addNewRow()
,现在一切正常初始化虚拟表单时,请执行以下操作:
希望它有帮助,编码愉快!
这是关于
ngOnChanges
的常见误解 .ngOnChanges
最适合Primitive Types,因为它们是按值传递的 .Javascript中的对象和数组通过引用传递 . 话虽如此,
ngOnChanges
正在寻找提供改变的输入值 . 在这种情况下, the reference to your Array is the input provided ,而不是Array中的值 . 因此,除非您将新数组传递给组件,否则ngOnChanges
将不会触发,因此不会重新呈现您的表单 .一个快速而肮脏的解决方案可能是每次在Parent端更新它时重新实例化Object / Array .
这将创建一个全新的数组,它应该反过来更改引用,并最终强制
ngOnChanges
触发孩子 .或者,您可以以某种方式将您的行转换为
Observable
并在子项内订阅它 . 就个人而言,Observables是一种更清晰的方式来处理原始类型之外的变化检测 . Here是关于通过服务进行父/子通信的文档的精彩文章 .