[英]How to patch form value to a recursive nested Angular Form?
最近,我在 StackOverflow 上提出了以下问题,并收到了一个惊人的回复,导致构建了一个递归嵌套的 Angular 表单: Angular Deeply Nested Reactive Form: Cannot find control with path on nested FormArray 。 这是作者写的关于同一问题的博客文章
这个递归嵌套的 Angular 表单让我继续构建组FormArrays
,所有这些都有一个group
object:
{
"conjunctor": null,
"conditions": [
{
"variable":
}
"groups": []
}
您可以添加多个conditions
实例并进一步嵌套groups
, 如此 StackBlitz所示
本质上,Form 组件已被拆分为多个组件: group-control
、 condition-form
和action-buttons-bar
(发出动作的按钮)。 这种方法可以满足我的一切需求,但是,我在通过这种递归方法修补表单值时遇到了麻烦。
到目前为止,我已经尝试发送 static 语句 object 并将其修补到整个表单本身,以及专门针对groups
object。 这是在
(我也在group-control
组件中尝试了相同和相似的方法)。 最终我计划使用来自 API 的数据来填充和修补这些值,但现在和测试,使用这个 static 数据
ngOnInit() {
const data = {
statement: {
groups: [
{
conjunctor: "and",
conditions: [
{
variable: "asdf"
}
],
groups: []
}
]
}
};
this._form.patchValue(data);
console.log(this._form.value);
}
是否可以在递归表单上修补statement
FormGroup
的表单值?
你的数据没有问题。 这很可能是时间问题。 在您可以修补任何值之前,表单必须是稳定的。 当您在OnInit
中执行此操作时,我想您正在构造函数中构建表单。 如果是这样,表单还没有准备好接收任何值。
解决这个问题的最简单方法是使用不舒服的setTimeout
。 但我想这只是为了测试。 在实际情况下,无论如何,数据可能需要一些时间才能获得。
如果您使用上述setTimeout
将其包装起来,则上面的示例将起作用:
ngOnInit() {
setTimeout(() => {
const data = {
statement: {
groups: [
{
conjunctor: "and",
conditions: [
{
variable: "asdf"
}
],
groups: []
}
]
}
};
this._form.patchValue(data);
console.log(this._form.value);
}, 50);
}
下面的动画 gif 显示了 3 个嵌套组中的补丁,最后一个嵌套在第二个组上。
您可以做的一件有趣的事情是根据您拥有的数据自动构建表单。 您可以通过分析进入ControlValueAccessor.writeValue
的数据来实现:
if (!value) {
return;
}
setTimeout(() => {
if (value && value.conditions && value.conditions.length) {
this._conditionsFormArray.clear();
value.conditions.forEach(c => this._addCondition());
}
if (value && value.groups && value.groups.length) {
this._groupsFormArray.clear();
value.groups.forEach(g => this._addGroup());
}
this._form.patchValue(value);
}, 50);
也许你已经注意到上面的setTimeout
,它的存在是因为我们在表单创建方法中有另一个 setTimeout(在OnInit
上调用),它在表单创建后向表单添加条件,而条件的创建本身是在setTimeout
中. 因此,我们必须等待它运行,否则this._conditionsFormArray.clear();
不会有任何影响 => 运行时不会创建任何条件。
private _createFormGroup() {
this._form = this._fb.group({
conjunctor: null,
conditions: this._fb.array([]),
groups: this._fb.array([])
});
// add one condition on the next tick, after the form creation
setTimeout(() => this._addCondition());
}
然后通过一些调整,我们可以得到以下结果(下面的 gif 是基于另一个Stackblitz 演示):
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.