我从下面了解了递归元素(树视图)的概念。
就我而言,我想将其与表格一起使用;假设递归地输入简单文本。表单的JSON结构如下。
我已经准备了以下代码。通过执行以下代码,我收到超出最大调用堆栈大小的错误。
下面是我的 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);
}
}
答案 0 :(得分:4)
实际上,Bhavik Patel的答案将解决以下错误问题:
超出了最大调用堆栈大小
但是由于Angular反应性表单的工作方式,您的表单绑定无法正常工作。 它依赖于依赖注入树,此模板看起来像:
FormGroup(testForm)
|__ FormArrayName('element')
|___ FormGroupName('0')
| ....
|___ FormGroupName(n)
您将始终仅在顶级控件上获得更新。
要解决此问题,您可以定义一些前缀,这些前缀将在嵌入式视图中更新。然后使用该前缀在树的每个级别上定义formGroup
:
<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>
答案 1 :(得分:2)
寻找元素列表而不是列表属性本身时,HTML代码中有一些更改。
这是解决问题后的更新代码。
component.html
<form [formGroup]="testForm" (ngSubmit)="onSubmit()">
<div formArrayName="element">
<ng-template #recursiveList let-element>
<div *ngFor="let item of element;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>
</form>
P.S .:当然,您也应该重构您的ts代码。它应该是动态生成的。