UNPKG

@cainiaofe/cn-ui-m

Version:
192 lines (191 loc) 11.5 kB
import { __assign, __awaiter, __generator, __rest } from "tslib"; import React from 'react'; import { useRequest } from 'ahooks'; import { createForm, onFieldValueChange } from '@formily/core'; import findLastKey from 'lodash/findLastKey'; import isEmpty from 'lodash/isEmpty'; import cloneDeep from 'lodash/cloneDeep'; import { CnForm } from "../../../form/cn-form"; import { CnLoading } from "../../cn-loading"; import { generateSchema, handleRequestService, useStateCallback, } from '../utils'; import { withNativeProps } from '@cainiaofe/cn-ui-common'; var DynamicContainerKey = 'dynamic_container'; var DynamicFormEffectsKey = 'dynamicFormAddEffectsKey'; export var CnDynamicForm = React.forwardRef(function (props, ref) { var prevFieldRef = React.useRef(null); var schema = props.schema, cols = props.cols, formProps = props.formProps, _remoteUrl = props.remoteUrl, requestConfig = props.requestConfig, initRequestConfig = props.initRequestConfig, submitRequestConfig = props.submitRequestConfig, initForm = props.form, initOnSubmit = props.onSubmit, restProps = __rest(props, ["schema", "cols", "formProps", "remoteUrl", "requestConfig", "initRequestConfig", "submitRequestConfig", "form", "onSubmit"]); var realSchema = React.useMemo(function () { return generateSchema(schema, cols); }, [schema, cols]); var _a = useStateCallback(__assign(__assign({}, requestConfig), { fromProps: true, url: (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.url) || _remoteUrl })), realRequestConfig = _a[0], setRequestConfig = _a[1]; var _b = useStateCallback(submitRequestConfig), realSubmitRequestConfig = _b[0], setSubmitRequestConfig = _b[1]; // 只有props内的requestConfig才存在initRequest;通过reLoad一定会执行run函数,因此何时调用reLoad,何时就会触发run; // 如果配置了url,但是没配置refreshDeps,则认为是初始渲染直接获取动态Schema var isInitRequest = React.useMemo(function () { return (realRequestConfig === null || realRequestConfig === void 0 ? void 0 : realRequestConfig.url) && (realRequestConfig === null || realRequestConfig === void 0 ? void 0 : realRequestConfig.fromProps) && isEmpty(realRequestConfig === null || realRequestConfig === void 0 ? void 0 : realRequestConfig.refreshDeps); }, [realRequestConfig]); // 远程Schema var _c = realRequestConfig || {}, service = _c.service, searchFormat = _c.searchFormat, refreshDeps = _c.refreshDeps, _d = _c.formatResult, formatResult = _d === void 0 ? function (res) { var _a; if (Array.isArray(res)) { return res; } else if (Array.isArray(res === null || res === void 0 ? void 0 : res.data)) { return res.data; } else if (Array.isArray((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.schema)) { return res.data.schema; } return []; } : _d, otherConfig = __rest(_c, ["service", "searchFormat", "refreshDeps", "formatResult"]); var requestService = React.useCallback(handleRequestService(realRequestConfig), [realRequestConfig]); var _e = useRequest(requestService, __assign({ ready: !!(realRequestConfig.url || service), manual: true }, otherConfig)), run = _e.run, runAsync = _e.runAsync, _f = _e.data, data = _f === void 0 ? [] : _f, loading = _e.loading; // 当props中requestConfig含有url && 且refreshDeps为空,则认为是isInitRequest,则调用run获取远程Schema。 React.useEffect(function () { if (isInitRequest) { run(); } }, [isInitRequest]); // 两种情况,一种是外部注入form,一种是内部createForm; // 需要判断,外部注入的话,需要获取form后,执行addEffects;内部生成的话需要获取form后,执行addEffects; var finalForm = React.useMemo(function () { // 如果涉及到状态的更新,须传入form实例 if (initForm) { initForm.addEffects(DynamicFormEffectsKey, function (form) { if (refreshDeps && refreshDeps.length > 0) { onFieldValueChange("*(".concat(refreshDeps.join(','), ")"), function (field) { run({ watchValue: field.value, formValues: form.getFormState().values, }); }); } }); return initForm; } return createForm(__assign(__assign({}, formProps), { effects: function (form) { if (refreshDeps && refreshDeps.length > 0) { onFieldValueChange("*(".concat(refreshDeps.join(','), ")"), function (field) { run({ watchValue: field.value, formValues: form.getFormState().values, }); }); } (formProps === null || formProps === void 0 ? void 0 : formProps.effects) && formProps.effects(form); } })); }, [initForm, realSchema]); var finalSchema = React.useMemo(function () { var _a, _b; // 清除字段模型、删除字段值,确保异步Schema不会值缓存 if (prevFieldRef.current && prevFieldRef.current.length > 0) { finalForm.clearFormGraph("*.".concat(DynamicContainerKey, ".*")); finalForm.deleteValuesIn("*.".concat(DynamicContainerKey, ".*")); } var cloneRealSchema = cloneDeep(realSchema); // 如果接口返回为空,则直接返回初始Schema; if (isEmpty(data)) return cloneRealSchema; // 如果接口返回不为空,则进行format;并构建最终Schema进行渲染 var initFormatData = formatResult(data); var formatData = []; if (Array.isArray(initFormatData)) { formatData = initFormatData; } else if (Array.isArray(initFormatData === null || initFormatData === void 0 ? void 0 : initFormatData.schema)) { formatData = initFormatData.schema; } else if (Array.isArray(initFormatData === null || initFormatData === void 0 ? void 0 : initFormatData.data)) { formatData = initFormatData.data; } else if (Array.isArray((_a = initFormatData === null || initFormatData === void 0 ? void 0 : initFormatData.data) === null || _a === void 0 ? void 0 : _a.schema)) { formatData = initFormatData.data.schema; } prevFieldRef.current = formatData; var realData = formatData; // 如果format后的data为空,则直接返回静态Schema if (isEmpty(realData)) { return cloneRealSchema; } else if (isEmpty(cloneRealSchema)) { // 不存在静态Schema时,直接使用接口返回进行渲染 return generateSchema(realData, cols); } else { // 存在静态Schema时,查找到静态Schema最后一个Properties对象,将接口返回Schema塞进去 var lastProperties = findLastKey(cloneRealSchema === null || cloneRealSchema === void 0 ? void 0 : cloneRealSchema.properties, function (o) { return !isEmpty(o === null || o === void 0 ? void 0 : o.properties); }); // 将异步获取的Schema,添加至最后一个properties中,确保异步Schema在表单最后位置 if (lastProperties) { var targetProperties = (_b = cloneRealSchema === null || cloneRealSchema === void 0 ? void 0 : cloneRealSchema.properties[lastProperties]) === null || _b === void 0 ? void 0 : _b.properties; targetProperties[DynamicContainerKey] = { type: 'void', 'x-component': 'CnFormGrid', 'x-component-props': { cols: cols, }, colSpan: 'full', properties: generateSchema(realData, cols, true), }; } } return cloneRealSchema; }, [data, realSchema, cols, finalForm]); // 初始值数据源 var _g = initRequestConfig || {}, initUrl = _g.url, initService = _g.service, _h = _g.formatResult, initFormatResult = _h === void 0 ? function (res) { return (res === null || res === void 0 ? void 0 : res.data) || res || {}; } : _h, initRestConfig = __rest(_g, ["url", "service", "formatResult"]); var initRequestService = React.useCallback(handleRequestService(initRequestConfig), [initRequestConfig]); var _j = useRequest(initRequestService, __assign({ ready: !!(initUrl || initService), manual: true }, initRestConfig)), initRun = _j.run, _k = _j.data, initData = _k === void 0 ? {} : _k; React.useEffect(function () { initRun(); }, [initRequestConfig]); React.useEffect(function () { var initialValues = initFormatResult(initData); if (!isEmpty(initialValues)) { finalForm.setInitialValues(initialValues); } }, [initData, finalForm]); // 提交数据源 var _l = realSubmitRequestConfig || {}, submitUrl = _l.url, submitService = _l.service, // eslint-disable-next-line _m = _l.formatResult, // eslint-disable-next-line submitFormatResult = _m === void 0 ? function (res) { return (res === null || res === void 0 ? void 0 : res.data) || res || {}; } : _m, submitRestConfig = __rest(_l, ["url", "service", "formatResult"]); var submitRequestService = React.useCallback(handleRequestService(realSubmitRequestConfig), [realSubmitRequestConfig]); var submitRun = useRequest(submitRequestService, __assign({ ready: !!(submitUrl || submitService), manual: true }, submitRestConfig)).run; // 根据onSubmit、submitRequestConfig重写onSubmit函数 var onSubmit = React.useCallback(function (values) { initOnSubmit && (initOnSubmit === null || initOnSubmit === void 0 ? void 0 : initOnSubmit(values)); submitRun({ formValues: values }); }, [initOnSubmit, realSubmitRequestConfig]); React.useImperativeHandle(ref, function () { return ({ reLoad: function (_requestConfig) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, new Promise(function (resolve) { setRequestConfig(__assign(__assign({}, _requestConfig), { fromProps: false }), resolve); })]; case 1: _a.sent(); return [4 /*yield*/, runAsync()]; case 2: _a.sent(); return [2 /*return*/]; } }); }); }, submit: function (_requestConfig) { setSubmitRequestConfig(_requestConfig, function () { var formValues = finalForm.getFormState().values; onSubmit(formValues); }); }, }); }); return withNativeProps(props, React.createElement(CnLoading, { visible: loading, style: { width: '100%' } }, React.createElement(CnForm, __assign({}, restProps, { form: finalForm, schema: finalSchema, onSubmit: onSubmit })))); }); CnDynamicForm.displayName = 'CnDynamicForm';