动态角度形状的递归组件-错误:找不到名称为的控件: [英] Recursive Component of Dynamic Angular Forms - ERROR Error: Cannot find control with name:
问题描述
我正在使用Reactive Form
;创建一个项目,该项目基于从JSON
文件创建Dynamic Form
的Recursive
组件。
来源
这是基于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
列表中所有FormControl
Form
如中的Green
右下角矩形所示。
在最后一个事件中。只显示两个控件!,但显示7个没有按钮的窗体控件!.
然后我的表单(变量this.form
)需要添加这些FormControl。
如何操作?
首先,我需要获取(父组件的)MainForm
和FormGroup
。
在我的父组件(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屋!