简体   繁体   English

来自 JSON 的 Angular 8 动态表单

[英]Angular 8 Dynamic Form From JSON

I'm trying to generate dynamic form recursively from JSON schema, but i'm struggling with form control not being found.我正在尝试从 JSON 模式递归生成动态表单,但我正在为找不到表单控件而苦苦挣扎。 Here is Code Examples.这是代码示例。

I get this error我收到这个错误

ERROR Error: Cannot find control with name: 'createdAt'错误错误:找不到名称为“createdAt”的控件

I tried different approaches but there is still a problem.我尝试了不同的方法,但仍然存在问题。 i know i miss something so please help.我知道我想念一些东西,所以请帮忙。 any help will be appreciated.任何帮助将不胜感激。

app.components.ts app.components.ts

export class AppComponent implements OnInit {
  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: TableFilter): 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应用程序组件.html

<form [formGroup]="filterForm" class="filter-form">
  <ng-template #recursiveList let-filterFields>
    <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 }"></ng-container>
        </div>
      </ng-container>
      <ng-template #default>
        <div class="col-md-3">
          <div class="form-group">
            <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>

You have to set the from group name on your #default ng-template您必须在#default ng-template 上设置 from 组名称

https://stackblitz.com/edit/angular-mc5zsd?file=src%2Fapp%2Fapp.component.html https://stackblitz.com/edit/angular-mc5zsd?file=src%2Fapp%2Fapp.component.html

在此处输入图片说明

Hi I am working on display and edit recursive JSON object as above but different structure.嗨,我正在显示和编辑上面的递归 JSON 对象,但结构不同。

Error: ERROR TypeError: Cannot read property 'name' of undefined
at Object.eval [as updateDirectives]

Here is my code https://stackblitz.com/edit/angular-nwuuan?file=src/app/app.component.html这是我的代码https://stackblitz.com/edit/angular-nwuuan?file=src/app/app.component.html

app.component.ts app.component.ts

import { Component } from '@angular/core';
import {FormGroup,FormControl,FormBuilder} from '@angular/forms'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
filterForm: FormGroup;
  filterFields: any[];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {    
this.filterFields = [ 
            {"signature": "[a][b][c][d]",
            "id": "start3",
            "passwd": "going",
            "url": "https://example.com",
            "code": "ME_GOOD",
            "type": "ABCD",
            "main":{
            "description": "development",
            "id": "98gbnuikmvgy6",
            "name": "satsba",
            "type": "dcba",
            "upload": "2019-09-04 18:17:23.222",
            "by": "example@gmail.com",
                        "version": "0.1"}}            ];

        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('field:',field);
    });
    // console.log('baseForm:',baseForm);
    return baseForm;
  }

  generateFormGroup(baseForm: FormGroup, field): FormGroup|FormControl {
  const formGroup = this.fb.group({});

    Object.keys(field).forEach(function(key) {
    formGroup.addControl(key, new FormControl(""));
    });
    console.log('formGroup',formGroup);
    return formGroup;
  }  
  }

app.component.html应用程序组件.html

<pre>{{filterForm?.value|json}}</pre>

<form [formGroup]="filterForm" class="filter-form">
    <ng-template #recursiveList let-filterFields let-fromGroup="fromGroup">
        <ng-container *ngFor="let filter of filterFields let i=index">
           <ng-container *ngFor="let item of filter | keyvalue">
           <p>{{item.key}}</p>

            <!-- <ng-container *ngIf="item.group; else default;"> -->
               
                <!-- <div  [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="form-group" >
                        <input [type]="text" [formControlName]="item.key" [name]="item.key" [value]="item.value"/>
                    </div>
            <!-- </ng-template> -->
             </ng-container>
        </ng-container>
    </ng-template>
    <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: filterFields }"></ng-container>
</form>

I am also following https://stackblitz.com/edit/angular-6n6nbd?file=src%2Fapp%2Fapp.component.html but no luck yet.我也在关注https://stackblitz.com/edit/angular-6n6nbd?file=src%2Fapp%2Fapp.component.html但还没有运气。

Thanks for help in advance.提前感谢您的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM