我是Angular的新手,正在尝试使用JSON数据创建动态表单。应从JSON数据的选项类型选择中选择条件。我尝试了以下代码,但它不起作用

<mat-card class="rahmendaten-container">
  <h3 class="page__header">{{stepCfg.stepHeading}}</h3>
  <div *ngIf="!!stepCfg.htmlContent" [innerHTML]="stepCfg.htmlContent">
  </div>
  <form [formGroup]="form" autocomplete="off" (ngSubmit)="onSubmit()">
    <mat-card-content class="page">
      <div class="page__container">
        <div *ngFor="let prop of formTemplate" class="container__row">
          <div [ngSwitch]="prop.type">
            <div *ngSwitchCase="'select'">
              <span [innerHTML]="prop.label"
              class="container__row__label"></span>
              <mat-form-field>
                <mat-select [formControlName]="onChange($event,prop)"
                [formControlName]="values[prop.label + i]">
                  <mat-option *ngFor="let option of prop.options"
                  [value]="option.value">{{option.label}}</mat-option>
                </mat-select>
              </mat-form-field>
            </div>
          </div>
        </div>
      </div>
    </mat-card-content>
  </form>
</mat-card>

输入脚本
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { MatDialog, MatDialogRef } from '@angular/material';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
    form:FormGroup;
    array: any[] = [];
    selectItems: any;
    formTemplate:any = form_template;
    stepCfg = {
      stepType: 'rahmendaten',
      stepHeading: '',
      stepIndex: 0,
      steps: [],
      firstStep: false,
      lastStep: false,
      onlyStep: false,
      data: {},
      htmlContent: ''
    };
    formDataObj = {};

  constructor() {}

  ngOnInit() {
    for (const prop of Object.keys(this.stepCfg.data)) {
      this.formDataObj[prop] = new
      FormControl(this.stepCfg.data[prop].value);
      this.formTemplate.push({
        key: prop,
        label: this.stepCfg.data[prop].label,
        type: this.stepCfg.data[prop].type,
        options: this.stepCfg.data[prop].options
      });
   }
   this.form = new FormGroup(this.formDataObj);
  }

  onChange(evt) {

    this.formTemplate.forEach(prop => {
      let options = prop.options.filter(x => x.value == evt)[0]
      var allLabels: string[] = this.formTemplate.map(x => x.label)

      if (options) {
        if (options.subfield &&
        !allLabels.includes(options.subfield.label)) {
          let obj = { ...options.subfield }
          this.formTemplate.push(obj)
        }
      }
    })
  }
}

 const form_template = [{
  "type": "select",
  "label": "Test1",
  "options": [
  {
      "value": "sped1",
      "label": "A Test GmbH",
      "subfield": {
        "type": "select",
        "label": "Subfield1",
        "options": [
          {
            "value": "subfieldvalue1",
            "label": "101"
          },
          {
            "value": "subfieldvalue1",
            "label": "101"
          },
        ]
       }
  },
  {
      "value": "sped2",
      "label": "Test2 GmbH"
  },
  {
     "value": "sped3",
     "label": "test3"
  },
  ]
}

]
导出默认的form_template

从@AdritaSharma获得宝贵的帮助之后;我已尝试过此方法,但它不起作用。

最佳答案

尝试这样:

<ng-container *ngFor="let item of form_template">
    <ng-container [ngSwitch]="item.type">
        <div *ngSwitchCase="'select'">
      {{item.label}}
            <select>
               <option *ngFor="let option of item.options" [value]="option.sped1">
                   {{option.label}}
               </option>
            </select>
        </div>
    </ng-container>
</ng-container>

Demo

为了适应子字段,我进行了一些更改:

Working Demo with Subfield

模板:
<ng-container *ngFor="let item of form_template">
    <ng-container [ngSwitch]="item.type">
        <div *ngSwitchCase="'select'">
            {{item.label}}
            <select (ngModelChange)="onChange($event,item.isChild)" [(ngModel)]="values[item.label + i]">
        <option *ngFor="let option of item.options" [value]="option.value">
          {{option.label}}
        </option>
        </select>
        </div>
    </ng-container>
</ng-container>

typescript :
 onChange(evt, isChild?) {

    this.form_template.forEach(item => {
      let options = item.options.filter(x => x.value == evt)[0]
      var allLabels: string[] = this.form_template.map(x => x.label)

      if (options) {

        if (options.subfield && !allLabels.includes(options.subfield.label)) {
          Object.assign(options.subfield, {isChild:true});
          this.form_template.push(options.subfield)
        }
      } else {
        this.form_template.forEach((x, i) => {
          x.options.forEach(y => {
            if (y.value != evt) {

              this.form_template.forEach((item, itemIndex) => {

                if (item.options.indexOf(y)) {
                  if (!isChild) {
                    this.form_template.splice(itemIndex, 1)
                  }
                }
              })
            }
          })
        })
      }
    })
  }

关于javascript - 如何有条件地使用JSON数据生成动态 Angular 形式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57980847/

10-12 03:56