Я понял концепцию рекурсивных элементов (древовидное представление) снизу.
В моем случае я хочу использовать его с формами; скажем, простой рекурсивный ввод текста. Структура формы 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);
}
}
2 ответа
Фактически, ответ Бхавика Пателя решит проблему с ошибкой:
Превышен максимальный размер стека вызовов
Но ваши привязки форм не будут работать должным образом из-за того, как работают реактивные формы 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>
В ваш 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-кода. Он должен генерироваться динамически.
Похожие вопросы
Связанные вопросы
Новые вопросы
angular
Вопросы по Angular (не путать с AngularJS), веб-фреймворку от Google. Используйте этот тег для угловых вопросов, которые не относятся к конкретной версии. Для более старой веб-платформы AngularJS (1.x) используйте тег angularjs.