本文将介绍如何动态创建表单组件,我们最终实现的效果如下:
在阅读本文之前,请确保你已经掌握 Angular 响应式表单和动态创建组件的相关知识,如果对相关知识还不了解,推荐先阅读一下 和 这两篇文章。对于已掌握的读者,我们直接进入主题。
创建动态表单
创建 DynamicFormModule
在当前目录先创建 dynamic-form
目录,然后在该目录下创建 dynamic-form.module.ts
文件,文件内容如下:
dynamic-form/dynamic-form.module.ts
@NgModule({
imports: [
CommonModule,ReactiveFormsModule
]
})
export class DynamicFormModule {}
创建完 DynamicFormModule
模块,接着我们需要在 AppModule 中导入该模块:
import { DynamicFormModule } from './dynamic-form/dynamic-form.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [browserModule,DynamicFormModule],declarations: [AppComponent],bootstrap: [AppComponent]
})
export class AppModule { }
创建 DynamicForm 容器
进入 dynamic-form
目录,在创建完 containers
目录后,继续创建 dynamic-form
目录,然后在该目录创建一个名为 dynamic-form.component.ts
的文件,文件内容如下:
@Component({
selector: 'dynamic-form',template: `
<form [formGroup]="form">
form: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.createGroup();
}
createGroup() {
const group = this.fb.group({});
this.config.forEach(control => group.addControl(control.name,this.fb.control('')));
return group;
}
}
由于我们的表单是动态的,我们需要接受一个数组类型的配置对象才能知道需要动态创建的内容。因此,我们定义了一个 config
输入属性,用于接收数组类型的配置对象。
此外我们利用了 Angular 响应式表单,提供的 API 动态的创建 FormGroup
对象。对于配置对象中的每一项,我们要求该项至少包含两个属性,即 (type) 类型和 (name) 名称:
- type - 用于设置表单项的类型,如
input
、select
、button
等 - name - 用于设置表单控件的 name 属性
在 createGroup()
方法中,我们循环遍历输入的 config
属性,然后利用 FormGroup
对象提供的 addControl()
方法,动态地添加新建的表单控件。
接下来我们在 DynamicFormModule 模块中声明并导出新建的 DynamicFormComponent
组件:
@NgModule({
imports: [
CommonModule,ReactiveFormsModule
],declarations: [
DynamicFormComponent
],exports: [
DynamicFormComponent
]
})
export class DynamicFormModule {}
现在我们已经创建了表单,让我们实际使用它。
使用动态表单
打开 app.component.ts 文件,在组件模板中引入我们创建的 dynamic-form
组件,并设置相关的配置对象,具体示例如下:
app.component.ts
interface FormItemOption {
type: string;
label: string;
name: string;
placeholder?: string;
options?: string[]
}
@Component({
selector: 'exe-app',template: `
上面代码中,我们在 AppComponent 组件类中设置了 config
配置对象,该配置对象中设置了三种类型的表单类型。对于每个表单项的配置对象,我们定义了一个 FormItemOption
数据接口,该接口中我们定义了三个必选属性:type、label 和 name 及两个可选属性:options 和 placeholder。下面让我们创建对应类型的组件。
自定义表单项组件
FormInputComponent
在 dynamic-form
目录,我们新建一个 components
目录,然后创建 form-input
、form-select
和 form-button
三个文件夹。创建完文件夹后,我们先来定义 form-input
组件:
form-input.component.ts
@Component({
selector: 'form-input',template: `
<div [formGroup]="group">