fix: form submission broken when using nested form

This commit is contained in:
chenos 2021-01-16 17:25:19 +08:00
parent dba1f1fbc6
commit 5f5bb0a258
6 changed files with 143 additions and 81 deletions

View File

@ -17,7 +17,8 @@ export function Create(props) {
params['associatedName'] = associatedName;
params['associatedKey'] = associatedKey;
} else {
params['resourceName'] = collection_name;
params['resourceName'] = props.resourceName;
params['resourceTarget'] = collection_name;
params['resourceKey'] = item.itemId;
}

View File

@ -6,6 +6,8 @@ import {
SchemaForm,
SchemaMarkupField as Field,
createFormActions,
FormSpy,
LifeCycleTypes,
createAsyncFormActions,
Submit,
Reset,
@ -32,6 +34,9 @@ export default forwardRef((props: any, ref) => {
const { data: schema = {}, loading } = useRequest(() => api.resource(target).getView({
resourceKey: 'form'
}));
const [state, setState] = useState<any>({});
const [form, setForm] = useState<any>({});
const [changed, setChanged] = useState(false);
const [visible, setVisible] = useState(false);
const [data, setData] = useState({});
const [title, setTitle] = useState('创建子字段');
@ -55,31 +60,18 @@ export default forwardRef((props: any, ref) => {
className={'noco-drawer'}
width={'40%'}
onClose={() => {
actions.getFormState(state => {
const values = cleanDeep(state.values);
const others = Object.keys(data).length ? cleanDeep({...data}) : cleanDeep(state.initialValues);
if (isEqual(values, others)) {
setVisible(false);
return;
}
for (const key in values) {
if (Object.prototype.hasOwnProperty.call(values, key)) {
const value = values[key];
const other = others[key];
if (!isEqual(value, other)) {
// console.log(value, other, values, others, state.initialValues);
Modal.confirm({
title: '表单内容发生变化,确定不保存吗?',
onOk() {
setVisible(false);
}
});
return;
}
if (changed) {
Modal.confirm({
title: '表单内容发生变化,确定不保存吗?',
onOk() {
setChanged(false);
setVisible(false);
}
}
});
} else {
setChanged(false);
setVisible(false);
});
}
}}
title={title}
footer={(
@ -89,11 +81,15 @@ export default forwardRef((props: any, ref) => {
}}
>
<Space>
<Button onClick={() => setVisible(false)}></Button>
<Button type={'primary'} onClick={async () => {
const { values = {} } = await actions.submit();
<Button onClick={() => {
setVisible(false);
onFinish && onFinish(values, index);
setChanged(false);
}}></Button>
<Button type={'primary'} onClick={async () => {
await form.submit();
// const { values = {} } = await actions.submit();
// setVisible(false);
// onFinish && onFinish(values, index);
}}></Button>
</Space>
</div>
@ -103,13 +99,50 @@ export default forwardRef((props: any, ref) => {
colon={true}
layout={'vertical'}
initialValues={data}
actions={actions}
onChange={(values) => {
setChanged(true);
}}
onSubmit={async (values) => {
setVisible(false);
setChanged(false);
onFinish && onFinish(values, index);
}}
// actions={actions}
schema={{
type: 'object',
properties: fields,
}}
expressionScope={scopes}
>
<FormSpy
selector={[
LifeCycleTypes.ON_FORM_MOUNT,
LifeCycleTypes.ON_FORM_SUBMIT_START,
LifeCycleTypes.ON_FORM_SUBMIT_END
]}
reducer={(state, action) => {
switch (action.type) {
case LifeCycleTypes.ON_FORM_SUBMIT_START:
return {
...state,
submitting: true
}
case LifeCycleTypes.ON_FORM_SUBMIT_END:
return {
...state,
submitting: false
}
default:
return state
}
}}
>
{({ state, form }) => {
setState(state)
setForm(form);
return <div/>
}}
</FormSpy>
</SchemaForm>
</Drawer>
);

View File

@ -101,7 +101,8 @@ export default function Table(props: SimpleTableProps) {
},
mutate: (values) => {
onChange(values.list);
console.log(values);
setDataSource(values.list);
console.log('mutate', values);
},
rowKey,
onMoved: async ({resourceKey, target}) => {

View File

@ -110,7 +110,7 @@ export function BooleanField(props: any) {
// console.log(props);
}}/>
}
console.log(props);
// console.log(props);
return (
<>{value ? <CheckOutlined style={{color: '#52c41a'}}/> : <CloseOutlined style={{color: '#f5222d'}}/>}</>
);

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useImperativeHandle, forwardRef, useRef } from 'react';
import React, { useState, useEffect, useImperativeHandle, forwardRef, useRef, createRef } from 'react';
import { Button, Drawer, Modal } from 'antd';
import { Tooltip, Input } from 'antd';
import {
@ -13,6 +13,8 @@ import {
FormValidator,
setValidationLanguage,
FormEffectHooks,
FormSpy,
LifeCycleTypes,
} from '@formily/antd';
import { merge } from '@formily/shared';
import { QuestionCircleOutlined } from '@ant-design/icons';
@ -25,8 +27,6 @@ import get from 'lodash/get';
import cleanDeep from 'clean-deep';
import scopes from './scopes';
const actions = createFormActions();
export const DrawerForm = forwardRef((props: any, ref) => {
console.log(props);
const {
@ -38,6 +38,9 @@ export const DrawerForm = forwardRef((props: any, ref) => {
associatedKey,
onFinish,
} = props;
const [state, setState] = useState<any>({});
const [form, setForm] = useState<any>({});
const [changed, setChanged] = useState(false);
console.log(associatedKey);
const { title, actionDefaultParams = {}, fields: properties ={} } = props.schema||{};
const [resourceKey, setResourceKey] = useState(props.resourceKey);
@ -57,8 +60,7 @@ export const DrawerForm = forwardRef((props: any, ref) => {
setVisible,
getData: run,
}));
console.log({onFinish});
return (
<Drawer
{...props}
@ -67,31 +69,19 @@ export const DrawerForm = forwardRef((props: any, ref) => {
width={'40%'}
className={'noco-drawer'}
onClose={() => {
actions.getFormState(state => {
const values = cleanDeep(state.values);
const others = Object.keys(data).length ? cleanDeep({...data, associatedKey, resourceKey}) : cleanDeep(state.initialValues);
if (isEqual(values, others)) {
setVisible(false);
return;
}
for (const key in values) {
if (Object.prototype.hasOwnProperty.call(values, key)) {
const value = values[key];
const other = others[key];
if (!isEqual(value, other)) {
// console.log(value, other, values, others, state.initialValues);
Modal.confirm({
title: '表单内容发生变化,确定不保存吗?',
onOk() {
setVisible(false);
}
});
return;
}
if (changed) {
Modal.confirm({
title: '表单内容发生变化,确定不保存吗?',
onOk() {
setChanged(false);
setVisible(false);
}
}
});
} else {
setChanged(false);
setVisible(false);
});
}
}}
title={title}
footer={(
@ -102,27 +92,11 @@ export const DrawerForm = forwardRef((props: any, ref) => {
>
<Button onClick={() => {
setVisible(false);
setChanged(false);
}}></Button>
<span style={{display: 'inline-block', width: 8}}> </span>
<Button type={'primary'} onClick={async () => {
const { values = {} } = await actions.submit();
console.log(values);
if (resourceKey) {
await api.resource(name).update({
resourceKey,
associatedKey,
values,
});
} else {
await api.resource(name).create({
associatedKey,
values,
});
}
setVisible(false);
// @ts-ignore
window.routesReload && window.routesReload();
onFinish && onFinish(values);
<Button loading={state.submitting} type={'primary'} onClick={async () => {
await form.submit();
}}></Button>
</div>
)}
@ -133,14 +107,67 @@ export const DrawerForm = forwardRef((props: any, ref) => {
layout={'vertical'}
// 暂时先这么处理,如果有 associatedKey 注入表单里
initialValues={{associatedKey, resourceKey, ...data}}
actions={actions}
// actions={actions}
schema={{
type: 'object',
properties,
}}
autoComplete={'off'}
expressionScope={scopes}
onChange={(values) => {
setChanged(true);
}}
onSubmit={async (values) => {
console.log(values);
console.log('submitsubmitsubmit', values);
if (resourceKey) {
await api.resource(name).update({
resourceKey,
associatedKey,
values,
});
} else {
await api.resource(name).create({
associatedKey,
values,
});
}
setVisible(false);
setChanged(false);
// @ts-ignore
window.routesReload && window.routesReload();
onFinish && onFinish(values);
}}
>
<FormSpy
selector={[
LifeCycleTypes.ON_FORM_MOUNT,
LifeCycleTypes.ON_FORM_SUBMIT_START,
LifeCycleTypes.ON_FORM_SUBMIT_END
]}
reducer={(state, action) => {
switch (action.type) {
case LifeCycleTypes.ON_FORM_SUBMIT_START:
return {
...state,
submitting: true
}
case LifeCycleTypes.ON_FORM_SUBMIT_END:
return {
...state,
submitting: false
}
default:
return state
}
}}
>
{({ state, form }) => {
setState(state)
setForm(form);
return <div/>
}}
</FormSpy>
</SchemaForm>
)}
</Drawer>

View File

@ -16,7 +16,7 @@ import { QuestionCircleOutlined } from '@ant-design/icons';
import scopes from './scopes';
export function FilterForm(props: any) {
const actions = createAsyncFormActions();
// const actions = createAsyncFormActions();
const { setVisible, onTrigger } = props;
const { title, fields: properties ={} } = props.schema||{};
return (
@ -24,7 +24,7 @@ export function FilterForm(props: any) {
colon={true}
layout={'vertical'}
initialValues={{}}
actions={actions}
// actions={actions}
onReset={() => {
setVisible && setVisible(false);
}}