接下来,整理一下动态表单的module.ts结构与其接口的模版
dynamic-form.module.ts
先上代码,再整理解析
import { TestFormComponent } from './components/test-form/test-form.component';
import { FormCheckboxComponent } from './components/form-checkbox/form-checkbox.component';
import { FormDateComponent } from './components/form-date/form-date.component';
import { FormInputComponent } from './components/form-input/form-input.component';
import { FormSelectComponent } from './components/form-select/form-select.component';
import { DynamicFormComponent } from './dynamic-form/dynamic-form.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
// import { ThirdPartyModule } from '../shared/third-party.module';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../shared/shared.module';
import { FormNgSelectComponent } from './components/form-ng-select/form-ng-select.component';
import { FormRadioComponent } from './components/form-radio/form-radio.component';
import { FormConfigInputComponent } from './components/form-config-input/form-config-input.component';
import { Injectable } from '@angular/core';
import { FormTextareaComponent } from './components/form-textarea/form-textarea.component';
import { FormConfigDateComponent } from './components/form-config-date/form-config-date.component';
import { ApplyRelativeComponent } from './components/apply-relative/apply-relative.component';
import { FormInputCheckComponent } from './components/form-input-check/form-input-check.component';
@NgModule({
imports: [
// TestFormComponent
FormsModule,
ReactiveFormsModule,
CommonModule,
SharedModule
],
// 申明模块内部成员
declarations: [
TestFormComponent,
FormCheckboxComponent,
FormDateComponent,
FormInputComponent,
FormSelectComponent,
DynamicFormComponent,
FormNgSelectComponent,
FormRadioComponent,
FormConfigInputComponent,
FormTextareaComponent,
FormConfigDateComponent,
ApplyRelativeComponent,
FormInputCheckComponent
],
exports: [
TestFormComponent,
FormCheckboxComponent,
FormDateComponent,
FormInputComponent,
FormSelectComponent,
DynamicFormComponent,
FormNgSelectComponent,
FormRadioComponent,
FormConfigInputComponent,
FormTextareaComponent,
FormConfigDateComponent,
ApplyRelativeComponent,
FormInputCheckComponent
],
// 动态加载的组件
entryComponents: [
FormCheckboxComponent,
FormDateComponent,
FormInputComponent,
FormSelectComponent,
FormNgSelectComponent,
FormRadioComponent,
FormConfigInputComponent,
FormTextareaComponent,
FormConfigDateComponent,
FormInputCheckComponent
],
// 创建根级别下的服务
providers: []
})
export class DynamicFormModule { }
跟普通组件的module一致,NgModule中也包含着 引入、声明、导出、入口组件
引入:引入了基础表单需要用到的相同
声明: 将相关我们做的动态模版组件都声明在此
导出:并将模版导出
动态加载组件:entryComponents
在这里将需要用到的组件模版进行加载,为什么有些不需要在entryComponents中写呢?
Angular使用entryComponents来启用“树震动”,即只编译项目中实际使用的组件,而不是编译所有在ngModule中声明但从未使用的组件
我的理解:告诉编译器这是一个动态添加的组件,在要添加时添加上
组件models中
动态表单的接口文件service:因为使用动态表单大多集中在对表单的展现,而不是数据的交互,所以service暂时可能没有用到,将数据的接口都写于具体的组件自己的service中
data-exchange.service.ts 配置数据交换service暂时没有用到,用于存放接口,但是我们还是将模版保留,以备后用
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
private messageSource1 = new BehaviorSubject('default message');
currentMessage1 = this.messageSource1.asObservable();
constructor() { }
// this.config.value
changeMessage(message: string) {
this.messageSource.next(message);
}
changeMessage1(message: string) {
this.messageSource1.next(message);
}
}
data.service.ts 也同样未用到,将接口都写于了具体的组件模块下
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
模版定义:
1、field-config.interface.ts
具体定义了一个input框的类型、样式、规则
import { ValidatorFn } from '@angular/forms';
import { IOption } from 'ng-select';
export interface FieldConfig {
label: ''; // label名称
field: ''; // 字段命名
type: ''; // 组件名称 input/date/select/radio等
isDisabled: boolean; // 只读
isRequired: boolean; // 必填项
unit: null; // 单位/后缀,例:元,公里,秒
pattern: null; // 验证提示信息
regExp: null; // 正则表达式
placeholder: '';
col: 4; // 布局
model: ''; // 绑定的实体对象
value: ''; // 默认值,好像我这个的数据库中少了这一列,对默认值的修改能力匮乏
startView?: any; // 日期组件开始视图 /文本框的行数
minView?: any; // 日期组件最小选择视图
options?: any; // 下拉选项 (单选选项)查询条件
isComponent?: boolean; // 是否是自定义组件
}
2、field.interface.ts
定义了一个字段的配置,config规定了字段的配置如上,group规定了formgroup表单的配置,model规定了字段所在实体。详细请见上一章。
import { FormGroup } from '@angular/forms';
import { FieldConfig } from './field-config.interface';
export interface Field {
config: FieldConfig;
group?: FormGroup;
model?: any;
}