Angular 8个递归形式

Angular 8 Recursive Form

我正在尝试从 JSON 模式递归生成动态表单,但我正在为找不到表单控件而苦苦挣扎。这是代码示例。

我收到这个错误

ERROR Error: Cannot find control with name: 'individualPerson'

我尝试了不同的方法,但仍然存在问题。我知道我想念一些东西,所以请帮忙。任何帮助将不胜感激。

模板端出现问题

app.components.ts

export class AppComponent {
  filterForm: FormGroup;
  filterFields: any[];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.filterFields = [
      {
        key: "common",
        title: "main fields",
        group: [
          {
            key: "createdAt",
            title: "Create Date",
            type: "date"
          },
          {
            key: "individualPerson",
            title: "Physical Person",
            group: [
              {
                key: "firstname",
                title: "First Name",
                type: "text"
              },
              {
                key: "lastname",
                title: "Last Name",
                type: "text"
              },
              {
                key: "phone",
                title: "Phone Number",
                type: "text"
              },
              {
                key: "citizenshipCountry",
                title: "Country",
                type: "text"
              }
            ]
          },
          {
            key: "legalPerson",
            title: "Legal Person",
            group: [
              {
                key: "brandname",
                title: "Brand Name",
                type: "text"
              },
              {
                key: "fullname",
                title: "Full Name",
                type: "text"
              },
              {
                key: "phone",
                title: "Phone",
                type: "text"
              },
              {
                key: "registrationCountry",
                title: "Country",
                type: "text"
              }
            ]
          }
        ]
      }
    ];

    this.filterForm = this.generateFilterForm();
  }

  generateFilterForm(): FormGroup {
    const baseForm = this.fb.group({});
    this.filterFields.forEach(field => {
      baseForm.addControl(field.key, this.generateFormGroup(baseForm, field));
    });
    console.log(baseForm);
    return baseForm;
  }

  generateFormGroup(baseForm: FormGroup, field): FormGroup {
    if (field.group) {
      const formGroup = this.fb.group({});
      field.group.forEach(item => {
        formGroup.addControl(item.key, this.generateFormGroup(formGroup, item));
      });
      return formGroup;
    } else {
      baseForm.addControl(field.key, new FormControl(""));
    }
    return baseForm;
  }
}

app.component.html

<form [formGroup]="filterForm" class="filter-form">
    <ng-template #recursiveList let-filterFields let-fromGroup="fromGroup">
        <ng-container *ngFor="let item of filterFields">
            <ng-container *ngIf="item.group; else default;">
                <p>{{item.title}}</p>
                <div class="row pb-4" [formGroupName]="item.key">
                    <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.group, fromGroup: {name: item.key} }"></ng-container>
                </div>
            </ng-container>
            <ng-template #default>       
                <div class="col-md-3">
                    <div class="form-group" [formGroupName]="fromGroup.name">
                        <input [type]="item.type" [formControlName]="item.key" [placeholder]="item.title" [name]="item.key" />
                    </div>
                </div>
            </ng-template>
        </ng-container>
    </ng-template>
    <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: filterFields }"></ng-container>
</form>

你的代码有些奇怪

1.-将函数 generateFormGroup 更改为 return 一个简单的 FormControl,以防 field.group=false

generateFormGroup(baseForm: FormGroup, field): FormGroup|FormControl {
    if (field.group) {
      const formGroup = this.fb.group({});
      field.group.forEach(item => {
        formGroup.addControl(item.key, this.generateFormGroup(formGroup, item));
      });
      return formGroup;
    }
      return new FormControl("");
  }}

递归 .html 将 formGroup 传递给模板并使用 [formControl][formGroup] (我无法使用 formControlName 获取它和 formGroupName)。有些人喜欢 - 看到我改变了一些放置 formGroup-

的地方
<form *ngIf="filterForm" [formGroup]="filterForm" class="filter-form">
    <ng-container *ngTemplateOutlet="recursiveList; 
          context:{ $implicit: filterFields,formGroup:filterForm }">
    </ng-container>
</form>

<ng-template #recursiveList let-filterFields let-formGroup="formGroup">
    <div class="form-group">
        <ng-container *ngFor="let item of filterFields">
            <p>{{item.title}}</p>
            <ng-container *ngIf="item.group; else default;">
                <div class="row pb-4">
                    <div [formGroup]="formGroup.get(item.key)">
                        <ng-container
                            *ngTemplateOutlet="recursiveList; 
                              context:{ $implicit: item.group, formGroup: formGroup.get( item.key)}">
                        </ng-container>
                    </div>
                </div>
            </ng-container>
            <ng-template #default>
                <div class="col-md-3">
                    <input [type]="item.type" [formControl]="formGroup.get(item.key)" 
                           [placeholder]="item.title" [name]="item.key" />
                </div>
            </ng-template>
        </ng-container>
    </div>
</ng-template>

您可以在stackblitz

中看到