如何动态创建控件



我有一个开关,它调用特定的方法来创建一个表单组:

switch (option.id) {
case DocumentBaseType.DocumentBaseRegister:
this.createDocumentsElectronCooperation();
break;
case DocumentBaseType.DocumentsElectronCooperation:
this.createDocumentsElectronCooperation();
break;
}

private createDocumentsElectronCooperation(): void {
this.form.addControl('date', this.createControl(null, []));
this.form.addControl('number', this.createControl(null, []));
this.form.addControl('documentTypes', this.formBuilder.array([]));
}
private createDocumentAnotherForm(): void {
this.form.addControl('name', this.createControl(null, [Validators.required]));
}

问题是,每次我都需要删除以前事件中显示的所有表单控件。对于exmaple,当我选择DocumentBaseType.DocumentBaseRegister时,我应该删除DocumentBaseType.DocumentsElectronCooperation的所有控件,反之亦然。

此外,表单的一个常见部分以所有表单类型呈现:

this.form = this.formBuilder.group({
appid: new FormControl(this.data?.appid, Validators.required),
rootDocumentType: new FormControl(null, Validators.required),
filename: new FormControl(null, Validators.required),
_ts: new FormControl(null),
});

如何在Angular中正确解决此问题?

如果你需要从几个额外的控件组中选择一个,你不需要以编程方式修改表单——我建议你尽可能避免这种情况,这通常是麻烦的来源。(例如,当重置表单时,在推送值之前,您需要确保它具有正确的结构。

相反,只需为每个专用控制集使用一个表单组:

this.form = this._formBuilder.group({
// The common controls for either document.
appId: […],
rootDocumentType: […],
filename: […],
_ts: […],
// A group for each of your document types
electronCooperationDetails: this.formBuilder.group({
date: […],
number: […],
documentTypes: this._formBuilder.array([]),
}),
baseRegisterDetails: this.formBuilder.groups({
name: […]
})
})

(我是FormBuilder的简写,为了清晰起见,省略了控件初始化。(

要打开正确的,请执行以下操作:

function enableIf(control, value) {
if (value) { control.enable(); } else { control.disable(); }
}
// … 
toggleDocumentDetails(baseTypeId) {
enableIf(this.form.controls['electronCooperationDetails'], 
baseTypeId === DocumentBaseType.DocumentsElectronCooperation);
enableIf(this.form.controls['electronCooperationDetails'], 
baseTypeId === DocumentBaseType. DocumentBaseType.DocumentBaseRegister);
}
// …
toggleDocumentDetails(option.id);

被禁用的表单子组的值将为undefined或不设置在this.form的值中;它也不会触发验证,而且对于大多数意图和目的来说,就好像表单组的控件不在那里一样。(在我的脑海中,我不确定用程序设置它的值是否有效,但我相信它确实有效,这将是一个优势。(

我放了一个更完整的演示如何在StackBlitz上动态显示不同的表单子组。不过,它使用了一个更简单的示例形式。

另一种方法是使用相同的函数创建所有控件

createForm(id)
{
const form=this.formBuilder.group({
appid: new FormControl(this.data?.appid, Validators.required),
rootDocumentType: new FormControl(null, Validators.required),
filename: new FormControl(null, Validators.required),
_ts: new FormControl(null),
});
switch (id)
{
case DocumentBaseType.DocumentBaseRegister:
form.addControl('date', this.createControl(null, []));
form.addControl('number', this.createControl(null, []));
form.addControl('documentTypes', this.formBuilder.array([]));
break;
case DocumentBaseType.DocumentsElectronCooperation:
form.addControl('name', this.createControl(null, [Validators.required]));
break;
}
return form;

}

然后你做

this.form=this.createForm(opt.id)

最新更新