在角度6中使用反应形式的递归形式(树形视图) [英] Recursive form (tree view) using Reactive forms in angular 6
问题描述
我从下面了解了递归元素(树视图)的概念.
I have understand concept of recursive elements(tree view) from below.
就我而言,我想将其与表格一起使用;假设递归地输入简单文本.表单的JSON结构如下.
In my case, I want to use it with forms; let's say simple text input recursively. JSON structure of form is as below.
我已经准备了以下代码.通过执行以下代码,我收到超出最大调用堆栈大小错误.
I have prepared below code.I am getting Maximum call stack size exceeded error by executing below code.
下面是我的 component.html 文件.
<form [formGroup]="testForm" (ngSubmit)="onSubmit()">
<div formArrayName="element">
<ng-template #recursiveList let-list>
<div *ngFor="let item of testForm.get('element').controls;let i=index;">
<div [formGroupName]="i">
<input type="text" formControlName="type">
</div>
<!-- {{item.get('element')?.controls?.length}} -->
<div *ngIf="item.get('element')?.controls?.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.get('element').controls }"></ng-container>
</div>
</div>
</ng-template>
<ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: testForm.get('element').controls }"></ng-container>
</div>
这是 component.ts 文件.
import { Component, OnInit } from '@angular/core';
import {FormControl, FormGroup, Validators, FormBuilder, FormArray} from '@angular/forms';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: [
'./test.component.scss'
]
})
export class TestComponent implements OnInit{
testForm:FormGroup;
element:any;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.testForm=this.formBuilder.group({
element:this.formBuilder.array([
this.formBuilder.group({
type:'',
element:this.formBuilder.array([
this.formBuilder.group({
type:'',
element:this.formBuilder.array([
])
})
])
})
])
})
}
onSubmit() {
console.log(this.testForm.value);
}
}
推荐答案
实际上,Bhavik Patel的答案将解决以下错误的问题:
In fact, Bhavik Patel's answer will solve the problem with the error:
超出了最大调用堆栈大小
Maximum call stack size exceeded
但是由于Angular反应性表单的工作方式,您的表单绑定无法正常工作. 它依赖于依赖注入树,此模板看起来像:
But your form bindings won't work properly due to how Angular reactive forms work. It relies on Dependency Injection tree which for this template looks like:
FormGroup(testForm)
|__ FormArrayName('element')
|___ FormGroupName('0')
| ....
|___ FormGroupName(n)
您将始终仅在顶级控件上获得更新.
You will always get updates only on your top level controls.
要解决此问题,您可以定义一些前缀,这些前缀将在嵌入式视图中更新.然后使用该前缀在树的每个级别上定义formGroup
:
To fix this issue you can define some prefix which will be updated inside embedded view. And then use that prefix to define formGroup
on each level of your tree:
<form class="tree" [formGroup]="testForm" (ngSubmit)="onSubmit()">
<ng-template #recursiveList let-controls let-prefix="prefix">
<ng-container *ngFor="let item of controls; let i = index">
<div class="tree-item" [formGroup]="testForm.get(prefix + i)">
<input type="text" formControlName="type">
</div>
<div class="sub-tree" *ngIf="item.get('element')?.controls?.length">
<ng-container
*ngTemplateOutlet="recursiveList; context:{ $implicit: item.get('element').controls, prefix: prefix + i + '.element.' }"></ng-container>
</div>
</ng-container>
</ng-template>
<ng-container
*ngTemplateOutlet="recursiveList; context:{ $implicit: testForm.get('element').controls, prefix: 'element.' }"></ng-container>
</form>
Ng-run Example
这篇关于在角度6中使用反应形式的递归形式(树形视图)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!