align="center">
在阅读本文之前,请确保你已经掌握 Angular 响应式表单和动态创建组件的相关知识,如果对相关知识还不了解,推荐先阅读一下 Angular 4.x Reactive Forms 和 Angular 4.x 动态创建组件 这两篇文章。对于已掌握的读者,我们直接进入主题。
创建动态表单
创建 DynamicFormModule
在当前目录先创建 dynamic-form 目录,然后在该目录下创建 dynamic-form.module.ts 文件,文件内容如下:
dynamic-form/dynamic-form.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ CommonModule, ReactiveFormsModule ] }) export class DynamicFormModule {}
创建完 DynamicFormModule 模块,接着我们需要在 AppModule 中导入该模块:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; 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 的文件,文件内容如下:
import { Component, Input, OnInit } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; @Component({ selector: 'dynamic-form', template: ` <form [formGroup]="form"> </form> ` }) export class DynamicFormComponent implements OnInit { @Input() config: any[] = []; 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 组件:
import { DynamicFormComponent } from './containers/dynamic-form/dynamic-form.component'; @NgModule({ imports: [ CommonModule, ReactiveFormsModule ], declarations: [ DynamicFormComponent ], exports: [ DynamicFormComponent ] }) export class DynamicFormModule {}
现在我们已经创建了表单,让我们实际使用它。
使用动态表单
打开 app.component.ts 文件,在组件模板中引入我们创建的 dynamic-form 组件,并设置相关的配置对象,具体示例如下:
app.component.ts
import { Component } from '@angular/core'; interface FormItemOption { type: string; label: string; name: string; placeholder?: string; options?: string[] } @Component({ selector: 'exe-app', template: ` <div> <dynamic-form [config]="config"></dynamic-form> </div> ` }) export class AppComponent { config: FormItemOption[] = [ { type: 'input', label: 'Full name', name: 'name', placeholder: 'Enter your name' }, { type: 'select', label: 'Favourite food', name: 'food', options: ['Pizza', 'Hot Dogs', 'Knakworstje', 'Coffee'], placeholder: 'Select an option' }, { type: 'button', label: 'Submit', name: 'submit' } ]; }
上面代码中,我们在 AppComponent 组件类中设置了 config 配置对象,该配置对象中设置了三种类型的表单类型。对于每个表单项的配置对象,我们定义了一个 FormItemOption 数据接口,该接口中我们定义了三个必选属性:type、label 和 name 及两个可选属性:options 和 placeholder。下面让我们创建对应类型的组件。
自定义表单项组件
FormInputComponent