arrays - 如何根据 Angular Reactive Forms 重新分配嵌套数组键?
问题描述
我正在努力为 Angular Reactive Forms 重新创建嵌套数组。
现有的嵌套数组。
nestedArray = [{
id:'abc',
required:true,
children:[{
id:"bcd",
parentId:"abc",
required:true,
children:[{
id:"cde",
parentId:"bcd",
required:false,
children:[{
id:"def",
parentId:"cde",
required:true,
children:[{
id:"efg",
parentId:"def",
required:false,
}]
},
{
id: "xyz",
parentId: "cde",
required: true,
}]
}]
}]
}]
为Angular Reactive Forms重新创建这个数组
nestedArray= this.fb.group({
abc: [''],
bcd: this.fb.group({
cde: [''],
efg: [''],
}),
});
上面的数组不正确,正在寻找以 Angular Reactive Form 创建子代的正确方法。
谢谢
解决方案
您需要创建一个返回 FormControl 或 FormGroup 的递归函数
form = new FormArray(this.nestedArray.map(x=>{
const group=new FormGroup({})
group.addControl(x.id,this.getGroup(x))
return group
}));
getGroup(data: any) {
if (!data.children)
return new FormControl()
const group = new FormGroup({});
if (data.children) {
data.children.forEach(x=>{
group.addControl(x.id,this.getGroup(x))
})
}
return group;
}
更新真的答案是错误的,因为我们没有对“父母”的形式控制。功能必须像
form = new FormArray(this.nestedArray.map(x=>this.getGroup(x)))
getGroup(data: any) {
if (!data.children)
{
return new FormControl)
}
const group = new FormGroup({});
group.addControl(data.id,new FormControl())
if (data.children) {
data.children.forEach(x=>{
group.addControl(x.id,this.getGroup(x))
})
}
return group;
}
好吧,问题是如何控制这种疯狂的形式。我们可以尝试创建一个“递归模板”,但我认为这是另一种更好的方法。想象一下,你有一个元素数组,每个元素都有三个属性:“index”、“label”和“control”。而control是对我们表单的FormControl的引用。然后我们可以构造一个 .html 之类的
<div *ngFor="let item of controls">
<span [style.margin-left]="item.index*10+'px'">{{item.label}}</span>
<input [formControl]="item.control">
<span *ngIf="item.control.errors?.required">*</span>
</div>
容易吗?直接使用[formControl]
and item.control.errors
oritem.control.touched
好吧,为此首先声明一个空数组
controls:any[]=[];
并更改功能,因此我们分两步添加组:1.-创建 formControl,2.-添加到组中,第三步是向我们的数组添加一个带有 {label,control 和“index”}的对象。当我们有一个递归函数想知道递归的“索引”时,这是很典型的。
//we pass as index 0 at first
form = new FormArray(this.nestedArray.map(x=>this.getGroup(x,0)))
getGroup(data: any,index:number) {
if (!data.children)
{
//create the control
const control=new FormControl('',data.required?Validators.required:null)
//add to the array this.controls
this.controls.push({control:control,label:data.id,index:index})
//return control
return control
}
const group = new FormGroup({});
index++
//create the control
const control=new FormControl('',data.required?Validators.required:null)
//add to the array this.controls
this.controls.push({control:control,label:data.id,index:index})
//add the control to the group
group.addControl(data.id,control)
if (data.children) {
data.children.forEach(x=>{
group.addControl(x.id,this.getGroup(x,index++))
})
}
return group;
}
好吧,在 stackblitz 中,将属性“value”添加到我们的复杂对象中,以展示如何做到这一点,我们使用“id”作为“标签”——也许我们的复杂对象需要一个新的属性标签——
推荐阅读
- amazon-web-services - 使用 aws cloudformation create-stack-instances 指定组织单位
- java - 以 Integer[] 为键搜索 Hashmap
- java - 比较两个哈希图(大小相同或不同)并存储奇数键
- dependency-injection - 是否可以指定要应用于 Kephas 中所有服务的服务元数据属性?
- android - Android Google Speech to text ApiStreamObserver 在 SynchronizationContext 中显示“未捕获的异常。恐慌!' 错误?
- javascript - 页面加载中止上的 Javascript 事件
- ruby-on-rails - Chartkick gem“没有给出块”运行时错误
- android - android - 如何在您的应用中直播 YouTube 频道(例如 Mecca Live)?
- c# - 使用转换器的 WPF SVG 图像绑定
- javascript - 为什么要使用 WebPack?