首页 > 解决方案 > 出现错误:使用 FormGroup 创建动态表单时找不到具有名称的控件:'' Angular

问题描述

我是 Angular 的新手。我想为调查创建一个动态表单。调查问题和输入类型是完全动态的,可能会根据区域而变化。我们从 API 调用中以 JSON 的形式获取它。

下面是代码片段。

.ts 文件

export class MaintenanceSurveyComponent implements OnInit {
  myFormTemplate: any = []; 
  myFormGroup: FormGroup = new FormGroup({});
  
  WOId;
  @Input() public user;
  constructor(private maintenanceService: MaintenanceRequestService) { }

  ngOnInit() {
   this. myFormGroup = new FormGroup({});
    this.maintenanceService.getSurveyquestions(this.user)
      .subscribe((res: any) => {
        this.myFormTemplate = JSON.parse(res);        
    });
    let group = {}
    this.myFormTemplate.forEach(input_template => {
      group[input_template.hMy] = new FormControl({ value: input_template.hMy});
    })
    this.myFormGroup = new FormGroup(group);    
  }

  onSubmit() {
    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.myFormGroup.getRawValue(), null, 4));
    console.log(this.myFormGroup.getRawValue());
    console.log("this is test");
  }

}

.html 文件

<form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()">
    <div class="modal-header border-0">
      <h5 class="modal-title" id="addMaintenanceRequestsTitle">Maintenance Survey</h5>
      <button type="button" class="close" data-dismiss="modal" aria-label="Close">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
    <div class="modal-body">
      <div class="row">
        <div class="col-lg-7">

          <div *ngFor="let form_elem of myFormTemplate">
            <div [ngSwitch]="form_elem.type">
              <div class="form-row">
                <div class="form-group col-md-12 mb-2" *ngSwitchCase="'textbox'">
                  <label class="text-sm font-weight-bold mb-1">{{form_elem.label}} </label>
                  <!--  <input type="text" formControlName="{{form_elem.hMy}}" />-->                
                  <input type="text"  formControlName="{{form_elem.hMy}}" required="{{form_elem.IsRequired}}" ngDefaultControl />
                </div>
              </div>
              <div class="form-row">
                <div class="form-group col-md-12 mb-2" *ngSwitchCase="'number'">
                  <label class="text-sm font-weight-bold mb-1">{{form_elem.label}} </label>
                  <!--<input type="number" formControlName="{{form_elem.label}}" />-->                  
                  <input type="number" formControlName="{{form_elem.hMy}}" required="{{form_elem.IsRequired}}" ngDefaultControl />
                </div>
              </div>
              <div class="form-row">
                <div class="form-group col-md-12 mb-2" *ngSwitchCase="'select'">
                  <!--<select formControlName="{{form_elem.label}}">-->               
                  <label class="text-sm font-weight-bold mb-1">{{form_elem.label}} </label>
                  <select  formControlName="{{form_elem.hMy}}" required="{{form_elem.IsRequired}}" ngDefaultControl >
                    <option *ngFor="let opt of form_elem.options">
                      {{opt}}
                    </option>
                  </select>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="modal-footer justify-content-start">
      <button type="submit" value="save" class="btn btn-primary">Submit</button>
    </div>
    <!--<input type="submit" value="save" />-->
  </form>

错误:

ERROR Error: Cannot find control with name: 'textbox88'
    at _throwError (forms.js:2293)
    at setUpControl (forms.js:2201)
    at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (forms.js:5427)
    at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (forms.js:6028)
    at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:5949)
    at checkAndUpdateDirectiveInline (core.js:21092)
    at checkAndUpdateNodeInline (core.js:29494)
    at checkAndUpdateNode (core.js:29456)
    at debugCheckAndUpdateNode (core.js:30090)
    at debugCheckDirectivesFn (core.js:30050)

我尝试了各种解决方案,但没有运气。我正在使用 Angular 8。感谢您对此的帮助。

标签: angulartypescript

解决方案


您需要在 subscribe 方法中移动表单创建并等待响应,因为它是异步调用。

export class MaintenanceSurveyComponent implements OnInit {
    myFormTemplate: any = [];
    myFormGroup: FormGroup = new FormGroup({});

    @Input() public user;
    constructor(private maintenanceService: MaintenanceRequestService) {}

    ngOnInit() {
        this.myFormGroup = new FormGroup({});
        this.maintenanceService.getSurveyquestions(this.user).subscribe((res: any) => {
            this.myFormTemplate = JSON.parse(res);

            let group = {};
            this.myFormTemplate.forEach((input_template) => {
                group[input_template.hMy] = new FormControl({ value: input_template.hMy });
            });
            this.myFormGroup = new FormGroup(group);
        });
    }

    onSubmit() {
        alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.myFormGroup.getRawValue(), null, 4));
        console.log(this.myFormGroup.getRawValue());
        console.log('this is test');
    }
}

推荐阅读