Отобразить динамическую c форму на основе раскрывающегося списка - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь создать динамическую c форму на основе раскрывающегося списка, но при попытке получить следующую ошибку:

field-builder.component.ts.FieldBuilderComponent.html:23 ERROR TypeError: Cannot read property 'valid' of undefined
  at FieldBuilderComponent.get isValid [as isValid] (field-builder.component.ts:45)
  at Object.updateDirectives (field-builder.component.ts.FieldBuilderComponent.html:26)
  at Object.debugUpdateDirectives [as updateDirectives] (core.js:45259)
  at checkAndUpdateView (core.js:44271)
  at callViewAction (core.js:44637)
  at execComponentViewsAction (core.js:44565)
  at checkAndUpdateView (core.js:44278)
  at callViewAction (core.js:44637)
  at execEmbeddedViewsAction (core.js:44594)
  at checkAndUpdateView (core.js:44272)

Мой FormComponent файл выглядит следующим образом:

export class FormTemplateComponent implements OnInit {
  public form: FormGroup;
  unsubcribe: any;
  types: type[];
  selectedType: type;
  isValid: boolean = false;
  uploadedFiles: any[] = [];

  constructor(private messageService: MessageService , private templateService : TemplateService) {
    this.types = [{ obj_type: "BS" }, { obj_type: "MS" }];
  }

  public fields = [];

  ngOnInit() {
    this.selectedType = this.types[1];
    this.getTemplates();
  }

  ngAfterViewInit() {
    // this.isSelected();
  }


  onUpload(event) {
    for (let file of event.files) {
      this.uploadedFiles.push(file);
      this.messageService.add({
        severity: "info",
        summary: "File Uploaded",
        detail: file.name
      });
    }

    console.log("eee", event);
  }

  ChangingValue() {
    if (this.selectedType.obj_type == "MS") {
        this.isValid= true 
        this.getTemplates(); }
      if (this.selectedType.obj_type == "BS") {
        this.isValid= false ;   
        this.getTemplates();   }
    //this.resetChildForm();

  }

  getTemplates() {
    this.templateService.getTemplates(this.selectedType.obj_type).subscribe( res =>{
      // if (this.selectedType.obj_type == "MS") {
      //   this.fields = res[0] ;      }
      // if (this.selectedType.obj_type == "BS") {
      //   this.fields = res[1] ;      }

      console.log(  "Eae", res );
      this.fields = res;
      // console.log(this.fields);
      // console.log(this.fields1);
      this.isValid = true;
    })
  }

  getFields1() {
    return this.fields;
  }
}

FormComponent. html выглядит следующим образом:

<p-toast [style]="{ marginTop: '80px' }"></p-toast>
<h1 class="text-center">Dynamic Form</h1><div class="ui-fluid ui-g" style="width: 80%; margin-left: 10%;">
<div class="form-group ui-g-12 ">
  <label for="sel1">Select Type:</label>
  <select
    class="form-control"
    [(ngModel)]="selectedType"
    (change)="ChangingValue()"
  >
    <option [ngValue]="type" *ngFor="let type of types">
      {{type.obj_type}}
    </option>
  </select>
</div> 
<div class="ui-g-12 ">
  <div class="card">
    <div class="card-header">Dynamic Forms</div>
    <div class="card-body">
      <!--
        <dynamic-form-builder
          *ngIf="!isValid"
          [fields]="getFields()"
        >
        </dynamic-form-builder>
      -->
      <dynamic-form-builder
        *ngIf="isValid"
        [fields]="getFields1()"
      ></dynamic-form-builder>
      <dynamic-form-builder
        *ngIf="!isValid"
        [fields]="getFields1()"
      ></dynamic-form-builder>
    </div>
  </div>
</div>

DynamicForm.ts выглядит следующим образом:

@Component({
  selector: 'dynamic-form-builder',
  template: `
    <form (ngSubmit)="onSubmit.emit(this.form.value)" [formGroup]="form" class="form-horizontal">
      <div *ngFor="let field of fields">
          <field-builder [field]="field" [form]="form"></field-builder>
      </div>
      <div class="form-row"></div>
      <div class="form-group row">
        <div class="col-md-3"></div>
        <div class="col-md-9">
          <button type="submit"  class="btn btn-primary">Save</button>
        </div>
      </div>
    </form>
  `,
})

export class DynamicFormBuilderComponent implements OnInit {
  @Output() onSubmit = new EventEmitter();
  @Input() fields: any[] = [];

  form: FormGroup;
  constructor() { }

  ngOnInit() {
    let fieldsCtrls = {};
    for (let f of this.fields) {
      if (f.type != 'checkbox') {
        fieldsCtrls[f.name] = new FormControl(f.value || '', Validators.required)
      } else {
        let opts = {};
        for (let opt of f.options) {
          opts[opt.key] = new FormControl(opt.value);
        }
        fieldsCtrls[f.name] = new FormGroup(opts)
      }
    }
  }
}

и я получаю сообщение об ошибке в этом файле fieldbuilder.ts :

@Component({
  selector: "field-builder",
  template: `
    <div class="form-group row" [formGroup]="form">
      <label
        class="col-md-3 text-center form-control-label"
        [attr.for]="field.label"
      >
        {{ field.label }}
        <strong class="text-danger" *ngIf="field.required">*</strong>
      </label>
      <div class="col-md-9" [ngSwitch]="field.type">
        <textbox *ngSwitchCase="'text'"   [field]="field" [form]="form"></textbox>
        <dropdown
          *ngSwitchCase="'dropdown'"
          [field]="field"
          [form]="form"
        ></dropdown>
        <checkbox
          *ngSwitchCase="'checkbox'"
          [field]="field"
          [form]="form"
        ></checkbox>
        <radio *ngSwitchCase="'radio'" [field]="field" [form]="form"></radio>
        <file *ngSwitchCase="'file'" [field]="field" [form]="form"></file>
        <div
          class="alert alert-danger my-1 p-2 fadeInDown animated"
          *ngIf="!isValid && isDirty"
        >
          {{ field.label }} is required
        </div>
      </div>
    </div>
  `
})

export class FieldBuilderComponent {
  @Input() field: any;
  @Input() form: any;

  get isValid() {
    return this.form.controls[this.field.name].valid;
  }

  get isDirty() {
    return this.form.controls[this.field.name].dirty;
  }

  constructor() {}
}

Я получаю сообщение об ошибке при изменении значения в раскрывающемся списке для отображения другого шаблона. Если имя ввода совпадает, оно выводится нормально, но если имя ввода поля изменяется по сравнению с исходным именем шаблона, это дает мне ошибку, в частности, это undefined

1 Ответ

0 голосов
/ 25 февраля 2020

так, ребята! Я решил эту проблему, просто отобразив форму Dynami c:


    ngOnChanges()
    {
     let fieldsCtrls = {};
        for (let f of this.fields) {
          if (f.type != 'checkbox') {
            fieldsCtrls[f.name] = new FormControl(f.value || '', Validators.required)
          } else {
            let opts = {};
            for (let opt of f.options) {
              opts[opt.key] = new FormControl(opt.value);
            }
            fieldsCtrls[f.name] = new FormGroup(opts)
          }
        }
      }
    }

вместо


    ngOnInit(){
    }

...