fix: InputTable列使用默认值时无法更新到数据域的问题 (#4970)

This commit is contained in:
RUNZE LU 2022-07-29 18:11:09 +08:00 committed by GitHub
parent e871f24c61
commit 7445ad96d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 138 additions and 6 deletions

View File

@ -1,8 +1,19 @@
import React = require('react'); import React = require('react');
import {render, screen, fireEvent} from '@testing-library/react'; import {
render,
screen,
fireEvent,
waitFor,
cleanup
} from '@testing-library/react';
import '../../../src'; import '../../../src';
import {render as amisRender} from '../../../src'; import {render as amisRender, clearStoresCache} from '../../../src';
import {makeEnv} from '../../helper'; import {makeEnv, wait} from '../../helper';
afterEach(() => {
cleanup();
clearStoresCache();
});
test('Renderer:input table', () => { test('Renderer:input table', () => {
const {container} = render( const {container} = render(
@ -55,6 +66,86 @@ test('Renderer:input table', () => {
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
}); });
test('Renderer: input-table with default value column', async () => {
const onSubmitCallbackFn = jest
.fn()
.mockImplementation((values: any, actions: any) => {
console.log({values: JSON.stringify(values), actions: actions});
return true;
});
const {container, getByText} = render(
amisRender(
{
type: 'page',
body: [
{
type: 'form',
api: '/api/mock2/form/saveForm',
data: {
table: [
{a: 'a1', b: 'b1'},
{a: 'a2', b: 'b2'},
{a: 'a3', b: 'b3'}
]
},
actions: [
{type: 'reset', label: 'Reset'},
{type: 'submit', label: 'Submit'}
],
body: [
{
type: 'input-table',
name: 'table',
label: 'Table',
addable: true,
needConfirm: false,
columns: [
{
label: 'A',
name: 'a',
type: 'input-text'
},
{
label: 'B',
name: 'b',
type: 'select',
options: ['b1', 'b2', 'b3']
},
{
label: 'C',
name: 'c',
value: '${a}',
type: 'input-text'
}
]
}
]
}
]
},
{
onSubmit: onSubmitCallbackFn
},
makeEnv({})
)
);
await wait(1000);
fireEvent.click(getByText('Submit'));
waitFor(() => {
expect(onSubmitCallbackFn).toHaveBeenCalledTimes(1);
expect(onSubmitCallbackFn.mock.calls[0][0]).toEqual({
table: [
{a: 'a1', b: 'b1', c: 'a1'},
{a: 'a2', b: 'b2', c: 'a2'},
{a: 'a3', b: 'b3', c: 'a3'}
]
});
});
});
test('Renderer:input table add', async () => { test('Renderer:input table add', async () => {
const {container, findByText} = render( const {container, findByText} = render(
amisRender( amisRender(

View File

@ -17,11 +17,16 @@ import {
ActionObject, ActionObject,
Api, Api,
Payload, Payload,
ApiObject ApiObject,
autobind,
isExpression
} from 'amis-core'; } from 'amis-core';
import {Button, Icon} from 'amis-ui'; import {Button, Icon} from 'amis-ui';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
import findIndex from 'lodash/findIndex'; import findIndex from 'lodash/findIndex';
import cloneDeep from 'lodash/cloneDeep';
import isEqual from 'lodash/isEqual';
import inRange from 'lodash/inRange';
import {TableSchema} from '../Table'; import {TableSchema} from '../Table';
import {SchemaApi} from '../../Schema'; import {SchemaApi} from '../../Schema';
import find from 'lodash/find'; import find from 'lodash/find';
@ -345,6 +350,7 @@ export default class FormTable extends React.Component<TableProps, TableState> {
emitValue() { emitValue() {
const items = this.state.items.filter(item => !item.__isPlaceholder); const items = this.state.items.filter(item => !item.__isPlaceholder);
const {onChange} = this.props; const {onChange} = this.props;
onChange?.(items); onChange?.(items);
} }
@ -503,7 +509,10 @@ export default class FormTable extends React.Component<TableProps, TableState> {
) )
); );
} else { } else {
setVariable(value, column.name, column.value); /** 如果value值设置为表达式则忽略 */
if (!isExpression(column.value)) {
setVariable(value, column.name, column.value);
}
} }
} }
}); });
@ -1074,6 +1083,37 @@ export default class FormTable extends React.Component<TableProps, TableState> {
this.setState({page}); this.setState({page});
} }
/**
* Table Row中数据更新到InputTable中
* columns形如[{name: 'a'}, {name: 'c', value: '${a}'}]使
*
* @param data
* @param rowIndex
*/
@autobind
handlePristineChange(data: Record<string, any>, rowIndex: string) {
this.setState(
prevState => {
const items = cloneDeep(prevState.items);
const index = Number(rowIndex);
if (
Number.isInteger(index) &&
inRange(index, 0, items.length) &&
!isEqual(items[index], data)
) {
items.splice(index, 1, data);
return {items};
}
return null;
},
() => {
this.emitValue();
}
);
}
removeEntry(entry: any) { removeEntry(entry: any) {
if (this.entries.has(entry)) { if (this.entries.has(entry)) {
this.entries.delete(entry); this.entries.delete(entry);
@ -1168,7 +1208,8 @@ export default class FormTable extends React.Component<TableProps, TableState> {
reUseRow: false, reUseRow: false,
offset, offset,
rowClassName, rowClassName,
rowClassNameExpr rowClassNameExpr,
onPristineChange: this.handlePristineChange
} }
)} )}
{(addable && showAddBtn !== false) || showPager ? ( {(addable && showAddBtn !== false) || showPager ? (