/** * @description: 公共EntityForm组件生成器 * @param {type} * @return: */ import React from 'react' import { FormProps } from '@ant-design/compatible/es/form'; import FromCreator, { IFormCreator } from './FormCreator' import { IFormItem, IFormItemLayout } from './declare' import { formLayoutEnums, FORM_TITEMS } from './enums' import { FormLifecycle } from './FormLifecycle' import { observable } from 'mobx'; import { Form } from '@ant-design/compatible'; export interface IFormProps extends FormProps { // self props } export interface EntityFormLifecycle { /** 表单被创建 */ onFormCreated?: (form: IFormProps['form']) => void /** 表单组件被加载 */ onFormMount?: () => void /** 表单组件被销毁 */ onFormDestroy?: () => void } declare type FormCreateOptionMessagesCallback = (...args: any[]) => string interface FormCreateOptionMessages { [messageId: string]: string | FormCreateOptionMessagesCallback | FormCreateOptionMessages } export interface IFormPresenterProps extends EntityFormLifecycle, IFormCreator { onFieldsChange?: (props: FormProps, fields: any, allFields: any) => void onValuesChange?: (props: FormProps, changedValues: any, allValues: any) => void mapPropsToFields?: (props: FormProps) => void validateMessages?: FormCreateOptionMessages withRef?: boolean name?: string } export interface IformLayout extends IFormItemLayout { type: string col?: number } export default class FormPresenter extends FormLifecycle { @observable protected HOCFormComponent: any protected form: IFormProps['form'] private formItems: IFormItem[] private initFormValues: any private rest private formLayout: IformLayout = { type: formLayoutEnums.FLOW, // 默认流式布局 } constructor(options: IFormPresenterProps) { super() const { formItems, initFormValues, onFormCreated, onFormDestroy, onFormMount, formLayout, ...rest } = options this.formItems = formItems?.slice(0) // 复制一份避免formItems被修改后产生bug this.initFormValues = initFormValues this.rest = rest if (formLayout) { this.formLayout = formLayout } /* onFormCreated */ if (onFormCreated) { this.listener.formCreatedListener.push(onFormCreated) } /* onFormMount */ if (onFormMount) { this.listener.formMountListener.push(onFormMount) } /* onFormDestroy */ if (onFormDestroy) { this.listener.formDestroyListener.push(onFormDestroy) } if (initFormValues) { this.initForm(this.formItems, initFormValues, rest) } } protected initForm = (formItems: IFormItem[], initFormValues: any, rest?: any): void => { const { onFieldsChange, onValuesChange } = rest let formCreated = false this.HOCFormComponent = Form.create({ onFieldsChange, onValuesChange })( ({ form, ...props }: any) => { this.form = form // rewrite validateFields method this.__validateFieldsAndScroll(form) this.__validateFields(form) this.__getFieldsValue(form) form.getFieldDecorator(FORM_TITEMS, { initialValue: formItems, getValueFromEvent: () => undefined, }) if (!formCreated) { formCreated = true // trigger lifeCycle listener this.triggerListener('formCreatedListener', form) } return ( ) }, ) } public setInitFormValues = (initFormValues: any) => { this.initFormValues = initFormValues // this.initForm(this.formItems, initFormValues, this.rest) } /** * @description: 返回FormComponent组件 * @param {type} * @return: */ public getFormComponent = (): Function => { if (this.HOCFormComponent) { return this.HOCFormComponent } return () =>
} /** * @description: 返回form实例 * @param {type} * @return: */ public getForm = (): IFormProps['form'] => { return this.form } /** * @description: 返回formItems * @param {type} * @return: */ public getFormItems = (): IFormItem[] => { return this.form.getFieldValue(FORM_TITEMS) } /** * @description: 返回formItem的下标 * @param {type} * @return: index */ public getFormItemIndex = (key: string): number => { return this.form.getFieldValue(FORM_TITEMS)?.findIndex(i => i.key === key) } /** * @description: 增加form item * @param {type} * @return: */ public addFormItem = (formItem: IFormItem, index?: number) => { if (this.form) { if (!formItem) return const { key } = formItem const formItems = this.form.getFieldValue(FORM_TITEMS) if (!formItems.find(((i: { key: string | number }) => i.key === key))) { if (typeof index === 'undefined') { formItems.push(formItem) } else { formItems.splice(index, 0, formItem) } this.form.setFieldsValue({ [FORM_TITEMS]: formItems, }) } else { console.warn(`Form field ${key} has already been created!`) } } else { console.warn('Form field cannot be set before form created!') } } /** * @description: remove form item * @param {type} * @return: */ public removeFormItem = (key: string) => { if (this.form) { const formItems = this.form.getFieldValue(FORM_TITEMS) const index = formItems.findIndex(i => i.key === key) if (index !== -1) { formItems.splice(index, 1) this.form.setFieldsValue({ [FORM_TITEMS]: formItems, }) } } else { console.warn('Form field cannot be set before form created!') } } public addFormList = (formItemList: any[]) => { if (this.form) { if (!formItemList) return let formItems = this.form.getFieldValue(FORM_TITEMS) formItems = formItems.concat(formItemList) this.form.setFieldsValue({ [FORM_TITEMS]: formItems, }) } else { console.warn('Form field cannot be set before form created!') } } public replaceFormList = (formItemList: any[], formValues) => { if (this.form) { if (!formItemList) return this.initFormValues = formValues this.initForm(formItemList, formValues, this.rest) } else { console.warn('Form field cannot be set before form created!') } } /** * @description: 更新form item * @param {type} * @return: */ public updateFormItem = (formItem: IFormItem) => { if (this.form) { const formItems = this.form.getFieldValue(FORM_TITEMS) const index = formItems.findIndex(i => i.key === formItem.key) formItems.splice(index, 1, formItem) this.form.setFieldsValue({ [FORM_TITEMS]: formItems, }) } else { console.warn('Form field cannot be set before form created!') } } /** * @description: 判断form是否已有某字段 * @param {type} * @return {type} */ public hasField = (key: string) => { const formItems = this.form.getFieldValue(FORM_TITEMS) if (!formItems.find((i: { key: string | number }) => i.key === key)) { return false } return true } /** * @description: 把form重置回初始值的状态 * @param {type} * @return {type} */ public resetFields = () => { console.log(this.initFormValues, 'initFormValues') this.form.setFieldsValue(this.initFormValues) } }