在角度6中使用反应形式的递归形式(树形视图) [英] Recursive form (tree view) using Reactive forms in angular 6

查看:111
本文介绍了在角度6中使用反应形式的递归形式(树形视图)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从下面了解了递归元素(树视图)的概念.

I have understand concept of recursive elements(tree view) from below.

链接1

就我而言,我想将其与表格一起使用;假设递归地输入简单文本.表单的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.

JOSN结构

我已经准备了以下代码.通过执行以下代码,我收到超出最大调用堆栈大小错误.

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运行示例

Ng-run Example

这篇关于在角度6中使用反应形式的递归形式(树形视图)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆