Создание динамической формы на основе файла json (файл json можно изменить нажатием кнопки после первого создания формы) - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь создать динамическую форму на основе https://angular.io/guide/dynamic-form. Я использую файл json для создания динамической формы.у меня 2 файла json (sbb.json, gx.json).Первый раз, когда я читаю из файла json и создаю форму, она работает отлично.Но у меня есть кнопка (Sbb), которая меняет файл с gx.json на sbb.json.но когда я нажимаю на это, это дает мне следующую ошибку:

ОШИБКА TypeError: "this.form.controls [this.question.key] не определено

, но когда янажмите кнопку "Gx", чтобы создать правильную форму без ошибок.

Код:

app.component.ts:

import { Component } from '@angular/core';
import SbbData from './sbb.json';
import GxData from './gx.json';
@Component({
  selector: 'app-root',
  template: `
    <div>
    <button type="button" (click)="callSbb()">SBB</button> 
    <button type="button" (click)="callGx()">GX</button> 
      <app-dynamic-form [questions]="questions"></app-dynamic-form>
    </div>
  `,
  providers: []
})
export class AppComponent{


  questions: any[];
  constructor() {
    this.questions = GxData;
  }

  callGx() {
    this.questions = GxData;

  }
  callSbb() {
    this.questions = SbbData;
  }

}

компонент динамической формы:

import { Component, Input, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { QuestionControlService } from '../question-control.service';

@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  providers: [QuestionControlService]
})
export class DynamicFormComponent implements OnInit {

  @Input() questions: any[] = [];
  form: FormGroup;
  payLoad = '';

  constructor(private qcs: QuestionControlService) { }

  ngOnInit() {
    this.form = this.qcs.toFormGroup(this.questions);
  }

  onSubmit() {
    this.payLoad = JSON.stringify(this.form.value);
  }
}

dynamic-form-component.html:

<form (ngSubmit)="onSubmit()" [formGroup]="form">

    <div *ngFor="let question of questions" class="form-row">
      <app-question [question]="question" [form]="form"></app-question>
    </div>

    <div class="form-row">
      <button type="submit" [disabled]="!form.valid">Save</button>
    </div>
</form>

question-control.service:

import { Injectable } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Injectable()
export class QuestionControlService {
  constructor() { }

  toFormGroup(questions: any[]) {
    let group: any = {};

    questions.forEach(question => {
      group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
        : new FormControl(question.value || '');
    });
    return new FormGroup(group);
  }
}

компонент динамической формы-вопроса:

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

@Component({
  selector: 'app-question',
  templateUrl: './dynamic-form-question.component.html'
})
export class DynamicFormQuestionComponent {
  @Input() question: any;
  @Input() form: FormGroup;
  get isValid() { return this.form.controls[this.question.key].valid; }
}

dynamic-form-question component.html:

<div [formGroup]="form">

  <div [ngSwitch]="question.controlType" class="checkbox_wrapper">

    <input *ngSwitchCase="'textbox'" [formControlName]="question.key" [id]="question.key" [type]="question.type" name="question.name">
    <label [attr.for]="question.key">{{question.label}}</label>
    <div *ngIf="question.child =='dropdown'" [formGroupName]="question.key">
      <select  [id]="question.key2"   >
        <option *ngFor="let opt of question.options" [attr.value]="opt.key" [attr.selected]="opt.select">{{opt.value}}</option>
      </select>
    </div>

    <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key" >
      <option *ngFor="let opt of question.options" [attr.value]="opt.key" [attr.selected]="opt.select">{{opt.value}}</option>
    </select>
    <!-- <label [attr.for]="question.key">{{question.label}}</label> -->
  </div>


  <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>

1 Ответ

0 голосов
/ 25 июня 2019

Чтобы решить эту проблему, я добавил метод ngOnChanges () в компонент динамической формы.

import { Component, Input, OnInit, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { QuestionControlService } from '../question-control.service';

@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  providers: [QuestionControlService]
})
export class DynamicFormComponent implements OnInit {

  @Input() questions: any[] = [];
  form: FormGroup;
  payLoad = '';

//newly added function

  ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {
      let change = changes[propName];
      // let curVal = JSON.stringify(change.currentValue);
      // let prevVal = JSON.stringify(change.previousValue);
      if (propName === 'questions') {
        this.form = this.qcs.toFormGroup(this.questions);
      }
    }
  }
  constructor(private qcs: QuestionControlService) { }

  ngOnInit() {
    this.form = this.qcs.toFormGroup(this.questions);
  }

  onSubmit() {
    this.payLoad = JSON.stringify(this.form.value);
    console.log(JSON.parse(this.payLoad));
  }
} 
...