好吧,让我先描述一下我实际想要解决的问题。
我需要我的表单模型才能拥有这个结构:
{
nested: {
first: 'one',
second: 'two',
third: 'three',
forth: 'four', ...
}, ...
}
子属性将根据用户输入动态添加到模型中,嵌套级别的数量可能会有所不同。
实现看起来像这样:
初始化表单:
ngOnInit() {
this.form = this.fb.group({
nested: this.getControls() // of type FormGroup
});
}
加载控件:
getControls(): FormGroup {
let group: FormGroup = new FormGroup({});
Object.keys(this.controls).forEach((key) => {
let control: FormControl = new FormControl(this.controls[key]);
group.addControl(key, control);
})
return group
}
带* ngFor的模板:
<div *ngFor="let control of form.get('nested').controls | keys; let i = index">
<label>{{ getLabel(i) }}</label>
<input [attr.placeholder]="control.value">
</div>
添加新的控制方法:
addControl(key, value) {
let control: FormControl = new FormControl(value)
this.form.get('nested').addControl(key, control);
this.cdf.detectChanges();
}
上的精简实施
现在,我遇到的问题是模型的值更新,但模板没有使用添加的输入重新渲染。
我试图强制更改检测,但它没有起作用。
我知道使用FormArray
提供了更多动态功能,但它会产生一个输出:
{
nested: [
{ first: 'one' },
{ second: 'two' },
{ third: 'three' },
{ forth: 'four' }, ...
], ...
}
这让我们回到了问题的根源。
当然,我可以利用一个函数,在将模型推送到数据库之前将模型转换回所需的格式,但是假设模型可以在树中的不同级别具有多个不同的属性,而对于某些我来说可能会显示为数组而某些可能不显示,事情很容易变得过于复杂。
这使我得到了FormGroup
,,但是如何在应用新输入时确保模板呈现?谢谢!
答案 0 :(得分:2)
我可以为您提供以下解决方案:
1)使用impure pipe
@Pipe({
name: 'keys',
pure: false
})
<强> Plunker Example 强>
2)添加控件后传递新引用
addControl(key, value) {
this.controls[key] = value;
this.form = this.fb.group({
nested: this.getControls()
});
}
<强> Plunker Example 强>
我还删除了getLabel
函数并将映射控件名称添加到管道
keyArr.forEach((key) => {
value[key].name = key;
dataArr.push(value[key])
})
另见