动态角度形状的递归组件-错误:找不到名称为的控件: [英] Recursive Component of Dynamic Angular Forms - ERROR Error: Cannot find control with name:

本文介绍了动态角度形状的递归组件-错误:找不到名称为的控件:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Reactive Form;创建一个项目,该项目基于从JSON文件创建Dynamic FormRecursive组件。

来源

这是基于Creating Dynamic Angular Forms with JSON

的Ionic改编

我调整了递归版本过程和其他更改!

我的代码位于Stackblitz

我将显示json-form.component.html文件的精简代码版本:

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <div fxLayout="column">
    <ng-container *ngFor="let control of jsonFormData?.controls">
      <div fxFlex="100%">
      
        <selects
          *ngIf="control.type === 'select'"
          [control]="control"
          [visible]="true"
        ></selects>
        
      </div>
    </ng-container>
  </div>
  <button mat-raised-button class="mt-1" color="primary">
    <em class="fa fa-save">Submit</em>
  </button>
</form>

您可以看到自定义组件是selects

现在,让我们看一下selects模板的Recursive使用代码。我再次减少了select.component.html文件的代码:

<form [formGroup]="form">
  <ng-container *ngIf="control?.children">
    <mat-form-field
      *ngIf="control.type === 'select' && control.visible"
      fxFlex="100%"
      hideRequiredMarker
    >
      <mat-label>{{ control.label }}</mat-label>
      <mat-select
        [formControlName]="control.name"
        [placeholder]="control.label"
        (selectionChange)="onSelectChange($event.value)"
      >
        <mat-option
          *ngFor="let child of control.children"
          [value]="child.value"
        >
          {{ child.label }}
        </mat-option>
      </mat-select>
    </mat-form-field>
  </ng-container>

  <ng-container *ngFor="let child of control?.children">
    <div fxFlex="100%">
      <selects *ngIf="child.type === 'select'" [control]="child"></selects>
    </div>
  </ng-container>
  
</form>

selects组件的递归代码为:

  <ng-container *ngFor="let child of control?.children">
    <div fxFlex="100%">
      <selects *ngIf="child.type === 'select'" [control]="child"></selects>
    </div>
  </ng-container>

错误示例如下:

ERROR
Error: Cannot find control with name: 'Petitioner (C2 -> P2)'

很遗憾,我找不到问题来解决它。

解决错误的线索?

编辑我怀疑并非所有组件都会立即显示,只有在单击"选择"时才会显示;然后不会仍创建该组件。

推荐答案

正如您在显示的视图中看到的,所有FormControl都在那里。 但是,当出现点击事件时。我用行console.log(this.form.value);console.log(this.form.value);显示了FormControl列表中所有FormControlForm

如中的Green右下角矩形所示。 在最后一个事件中。只显示两个控件!,但显示7个没有按钮的窗体控件!. 然后我的表单(变量this.form)需要添加这些FormControl。

如何操作?

首先,我需要获取(父组件的)MainFormFormGroup

在我的父组件(JsonFormComponent)中,来自json-form.component.ts文件:

export class JsonFormComponent implements OnChanges {
  @Input() jsonFormData: JsonFormData;

  public myForm: FormGroup = this.fb.group({});
  public myFormBuilder: FormBuilder;

  constructor(private fb: FormBuilder) {
    this.myFormBuilder = fb;
  }

现在,我的父组件有public myForm: FormGroup...public myFormBuilder: FormBuilder;!。

下一步是在selects.component.ts文件中的每个子组件中创建局部变量。

export class SelectsComponent implements OnInit {
  public form: FormGroup;
  @Input() formBuilder: FormBuilder;

  constructor(private rootFormGroup: FormGroupDirective) {}

  ngOnInit(): void {
    this.form = this.rootFormGroup.form;
  }

现在,我的子组件有public form: FormGroup...@Input() formBuilder: FormBuilder;!。

下一步是将该对象传递给我的子组件:

要传递(或关联)myForm(FormGroup)的解决方案来自于此post。 但是,myFormBuilder的关系是在json-form.component.html文件中完成的。

    <selects
      *ngIf="control.type === 'select'"
      [control]="control"
      [visible]="true"
      (addControl)="onAddControl($event)"
      [formBuilder]="myFormBuilder"
    ></selects>

具体在行:[formBuilder]="myFormBuilder"

对于递归,在selects.component.html文件中

  <ng-container *ngFor="let child of control?.children">
    <div fxFlex="100%">
      <selects
        *ngIf="child.type === 'select'"
        [control]="child"
        [formBuilder]="formBuilder"
      ></selects>
    </div>
  </ng-container>

具体在行:[formBuilder]="formBuilder"

现在,在我的文件selects.component.ts的子组件中,我创建了这个方法:

  private newControl(control: JsonFormControls) {
    this.form.addControl(
      control.name,
      this.formBuilder.control(control.value, getValidators(control))
    );
    control.visible = true;
  }

最后:我更改了方法,以便添加需要显示的FormControl

  public onSelectChange(event: MatSelectChange) {
    console.log(this.form.value);
    this.control.value = event + '';
    if (this.control.children) {
      this.recursiveConcealer(this.control.children);
      const child = this.control.children.find(
        (child) => child.value === event + ''
      );
      this.newControl(child);
      if (child.siblings) {
        for (let sibling of child.siblings) {
          this.newControl(sibling);
        }
      }
    }
  }

请特别注意this.newControl(child);this.newControl(sibling);行。

正如您在Blue矩形中看到的,错误已消失。

注意:不是唯一的解决方案,这里是关于此主题的questionHow can I pass the FormGroup of a parent component to its child component using the current Form API

这篇关于动态角度形状的递归组件-错误:找不到名称为的控件:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆