littleone2018
3/9/2020 - 10:47 AM

组件

组件

/**
 * 弹窗表单组件,用法为modalForm({...}),  onSubmit需要返回一个promise,内部会自动处理loading和关闭modal
 */

import React, { useState } from 'react'
import { Modal } from 'antd'
import { render, unmountComponentAtNode } from 'react-dom'
import { SchemaForm, createFormActions, IFormEffect, IFormSubmitResult, ISchema } from '@formily/antd'

const actions = createFormActions()

interface Props {
  schema: {
    [key: string]: ISchema
  }
  effects?: IFormEffect
  defaultValue?: object
  title: string
  width?: number
  labelCol?: number,
  onSubmit: (values: object) => Promise<any>
}

export default ({
  schema,
  effects,
  onSubmit,
  defaultValue,
  title,
  width = 600,
  labelCol = 4
}: Props) => {
  const root = document.createElement('div')
  document.body.appendChild(root)

  const handleCancel = () => {
    unmountComponentAtNode(root)
    document.body.removeChild(root)
  }

  const handelSubmit = () =>
    actions.submit().then(({ values }: IFormSubmitResult) => onSubmit(values))

  const Content = () => {
    const [loading, setLoading] = useState(false)

    const handleOk = () => {
      setLoading(true)
      handelSubmit()
        .then(() => {
          setLoading(false)
          handleCancel()
        })
        .catch(() => setLoading(false))
    }

    return (
      <Modal
        visible
        centered
        title={title}
        width={width}
        maskClosable={false}
        confirmLoading={loading}
        onCancel={handleCancel}
        onOk={handleOk}
      >
        <SchemaForm
          actions={actions}
          effects={effects}
          labelCol={{ span: labelCol }}
          wrapperCol={{ span: 24 - labelCol }}
          schema={{
            type: 'object',
            properties: schema
          }}
          defaultValue={defaultValue}
        />
      </Modal>
    )
  }

  render(<Content />, root)
}