订阅后生成表单会出现“期望表单组实例”错误

时间:2019-05-08 07:22:26

标签: angular typescript

我正在尝试以6号角构建一个包含表单的页面,使用从projects调用中检索到的数据填充REST下拉菜单。当我使用硬编码数据在没有订阅的情况下测试所有内容时,表单可以完美运行。但是,当我添加rest调用并在订阅范围内构建表单时,它在控制台中出现了3次4次FormGroup错误:

  

错误错误:formGroup需要一个FormGroup实例。请传递一个。

我不确定为什么没有订阅调用时表单可以完美运行,也许是异步调用的问题?

我看到了this解决方案,但对我来说不起作用,只能完全删除表格

注意:我也有其他一些页面可以实现此目的,但是没有一个页面有此问题。

component.ts

import { Component, OnInit, ViewChild, ViewContainerRef, AfterContentInit } from '@angular/core';
import { Location } from '@angular/common';
import { TranslatePipe } from 'src/app/pipes/translate/translate.pipe';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { DynamicTextFieldService } from 'src/app/services/dynamic-loading/dynamic-text-field/dynamic-text-field.service';
import { DynamicDropdownService } from 'src/app/services/dynamic-loading/dynamic-dropdown/dynamic-dropdown.service';
import { DynamicTextAreaService } from 'src/app/services/dynamic-loading/dynamic-text-area/dynamic-text-area.service';
import { CustomSearchService } from 'src/app/services/search/custom-search/custom-search.service';

@Component({
  selector: 'app-knowledge-base-create',
  templateUrl: './knowledge-base-create.component.html',
  styleUrls: ['./knowledge-base-create.component.scss']
})
export class KnowledgeBaseCreateComponent implements OnInit, AfterContentInit {

  @ViewChild('f1', { read: ViewContainerRef }) f1;
  @ViewChild('f2', { read: ViewContainerRef }) f2;
  @ViewChild('f3', { read: ViewContainerRef }) f3;
  @ViewChild('f4', { read: ViewContainerRef }) f4;

  kbForm: FormGroup;

  projectsList: any;

  constructor(private location: Location,
    private translate: TranslatePipe,
    private dynamictextfield: DynamicTextFieldService,
    private fb: FormBuilder,
    private dynamicdropdown: DynamicDropdownService,
    private dynamictextarea: DynamicTextAreaService,
    private search: CustomSearchService) { }

  ngOnInit() {
    this.search.searchCall("PP_1_Projects", "", "", true).subscribe(
      response => {
        response = response.records;
        this.projectsList = response;
        this.buildForm();
      },
      error => {
        console.log(error);
      }
    );
  }

  buildForm() {
    this.kbForm = this.fb.group({
      'f1': ['', Validators.required],
      'f2': ['', Validators.required],
      'f3': ['', Validators.required],
      'f4': ['', Validators.required]
    })
  }

  ngAfterContentInit() {
    this.buildf1();
    this.buildf2();
    this.buildf3();
    this.buildf4();
  }

  goBack() {
    this.location.back();
  }

  buildf1() {
    let data = {
      reference: this.f1,
      type: "text",
      class: "form-control",
      placeholder: "Article Name", //TODO: change to translate
      id: "f1",
      autoComplete: false,
      formControlName: "f1",
      group: this.kbForm
    }
    this.dynamictextfield.loadTextField(data);
  }

  buildf2() {
    let data = this.projectsList;
    let array = {
      reference: this.f2,
      id: "f2",
      formControlName: "f2",
      group: this.kbForm,
      data: data,
      placeholder: "Select Project Name"
    }
    this.dynamicdropdown.loadDropdown(array);
  }

  buildf3() {
    let data = [
      {
        "name": "New"
      },
      {
        "name": "Open"
      },
      {
        "name": "Closed"
      }
    ]

    let array = {
      reference: this.f3,
      id: "f3",
      formControlName: "f3",
      group: this.kbForm,
      data: data,
      placeholder: "Select Status"
    }
    this.dynamicdropdown.loadDropdown(array);
  }

  buildf4() {
    let data = {
      reference: this.f4,
      placeholder: "Enter any notes here..", //TODO: change to translate
      id: "f4",
      formControlName: "f4",
      group: this.kbForm
    }
    this.dynamictextarea.loadTextArea(data);
  }


}

component.html

<div>
  <app-toolbar></app-toolbar>
  <app-side-nav></app-side-nav>
  <div class="container-fluid">
    <app-button description="{{ 'pages[knowledge_base][buttons][go_back]' | translate }}" class="btn btn-danger btn-md custom" (callFunction)="goBack()"></app-button>
    <div class="card-group">
      <div class="card p-4">
        <form [formGroup]="kbForm">
          <h2 class="col-md-6">Create New Knowledge Base Article</h2>
          <div class="col-md-3">
            <div #f1 class="input"></div>
            <div #f2 class="input"></div>
            <div #f3 class="input"></div>
          </div>
          <div class="col-md-6">
            <div #f4 class="input"></div>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

找到了一种解决方法,this.buildf2();函数正在使用来自保存在projectsList中的响应数据,因此我没有向响应组添加this.buildForm();,而是添加了此函数。它使用更新后的响应正确呈现了div。

像这样:

import { Component, OnInit, ViewChild, ViewContainerRef, AfterContentInit } from '@angular/core';
import { Location } from '@angular/common';
import { TranslatePipe } from 'src/app/pipes/translate/translate.pipe';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { DynamicTextFieldService } from 'src/app/services/dynamic-loading/dynamic-text-field/dynamic-text-field.service';
import { DynamicDropdownService } from 'src/app/services/dynamic-loading/dynamic-dropdown/dynamic-dropdown.service';
import { DynamicTextAreaService } from 'src/app/services/dynamic-loading/dynamic-text-area/dynamic-text-area.service';
import { CustomSearchService } from 'src/app/services/search/custom-search/custom-search.service';
import { CustomValidators } from 'src/app/views/forgot-password/reset-password/custom-validators';


@Component({
  selector: 'app-knowledge-base-create',
  templateUrl: './knowledge-base-create.component.html',
  styleUrls: ['./knowledge-base-create.component.scss']
})
export class KnowledgeBaseCreateComponent implements OnInit, AfterContentInit {

  @ViewChild('f1', { read: ViewContainerRef }) f1;
  @ViewChild('f2', { read: ViewContainerRef }) f2;
  @ViewChild('f3', { read: ViewContainerRef }) f3;
  @ViewChild('f4', { read: ViewContainerRef }) f4;

  projectsList: any;

  kbForm: FormGroup;

  constructor(private location: Location,
    private translate: TranslatePipe,
    private dynamictextfield: DynamicTextFieldService,
    private fb: FormBuilder,
    private dynamicdropdown: DynamicDropdownService,
    private dynamictextarea: DynamicTextAreaService,
    private search: CustomSearchService) { }

  ngOnInit() {
    this.buildForm(); //removed call from here, replaced with buildForm()
  }

  buildForm() {
    this.kbForm = this.fb.group({
      'f1': ['', Validators.required],
      'f2': ['', Validators.required],
      'f3': ['', Validators.required],
      'f4': ['', Validators.required]
    })
  }

  ngAfterContentInit() {
    this.buildf1();
    this.buildf3();
    this.buildf4();
    this.retrieveProjectData(); //added function here, renders perfectly
  }

  retrieveProjectData() { //created this function instead, added to afterContentInit
    this.search.searchCall("PP_1_Projects", "", "", true).subscribe(
      response => {
        response = response.records;
        this.projectsList = response;
        this.buildf2();
        console.log(response);
      },
      error=>{
        console.log(error);
      }
    )
  }

  goBack() {
    this.location.back();
  }

  buildf1() {
    let data = {
      reference: this.f1,
      type: "text",
      class: "form-control",
      placeholder: "Article Name", //TODO: change to translate
      id: "f1",
      autoComplete: false,
      formControlName: "f1",
      group: this.kbForm
    }
    this.dynamictextfield.loadTextField(data);
  }

  buildf2() {
    let data: any;
    if (this.projectsList == undefined) {
      data = [
        {
          "name": ""
        }
      ]
    } else {
      data = this.projectsList;
    }

    let array = {
      reference: this.f2,
      id: "f2",
      formControlName: "f2",
      group: this.kbForm,
      data: data,
      placeholder: "Select Project Name"
    }
    this.dynamicdropdown.loadDropdown(array);
  }

  buildf3() {
    let data = [
      {
        "name": "New"
      },
      {
        "name": "Published"
      },
      {
        "name": "Unpublished"
      }
    ]

    let array = {
      reference: this.f3,
      id: "f3",
      formControlName: "f3",
      group: this.kbForm,
      data: data,
      placeholder: "Select Status"
    }
    this.dynamicdropdown.loadDropdown(array);
  }

  buildf4() {
    let data = {
      reference: this.f4,
      placeholder: "Enter any notes here..", //TODO: change to translate
      id: "f4",
      formControlName: "f4",
      group: this.kbForm
    }
    this.dynamictextarea.loadTextArea(data);
  }

  get form() {
    return this.kbForm.controls;
  }


}