Skip to content

Commit 99f669a

Browse files
author
maurice
authored
fix: fix ArrayTable skipping validation of new page (#3117)
1 parent d24168b commit 99f669a

File tree

3 files changed

+155
-15
lines changed

3 files changed

+155
-15
lines changed

packages/antd/src/array-table/index.tsx

+47-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import React, { Fragment, useState, useRef, useEffect } from 'react'
1+
import React, {
2+
Fragment,
3+
useState,
4+
useRef,
5+
useEffect,
6+
createContext,
7+
useContext,
8+
} from 'react'
29
import { Table, Pagination, Space, Select, Badge } from 'antd'
310
import { PaginationProps } from 'antd/lib/pagination'
411
import { TableProps, ColumnProps } from 'antd/lib/table'
@@ -13,7 +20,7 @@ import {
1320
RecursionField,
1421
ReactFC,
1522
} from '@formily/react'
16-
import { isArr, isBool } from '@formily/shared'
23+
import { isArr, isBool, isFn } from '@formily/shared'
1724
import { Schema } from '@formily/json-schema'
1825
import { usePrefixCls } from '../__builtins__'
1926
import { ArrayBase, ArrayBaseMixins } from '../array-base'
@@ -42,6 +49,12 @@ type ComposedArrayTable = React.FC<React.PropsWithChildren<TableProps<any>>> &
4249
Column?: React.FC<React.PropsWithChildren<ColumnProps<any>>>
4350
}
4451

52+
interface PaginationAction {
53+
totalPage?: number
54+
pageSize?: number
55+
changePage?: (page: number) => void
56+
}
57+
4558
const SortableRow = SortableElement((props: any) => <tr {...props} />)
4659
const SortableBody = SortableContainer((props: any) => <tbody {...props} />)
4760

@@ -198,6 +211,11 @@ const StatusSelect: ReactFC<IStatusSelectProps> = observer(
198211
}
199212
)
200213

214+
const PaginationContext = createContext<PaginationAction>({})
215+
const usePagination = () => {
216+
return useContext(PaginationContext)
217+
}
218+
201219
const ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = (props) => {
202220
const [current, setCurrent] = useState(1)
203221
const prefixCls = usePrefixCls('formily-array-table')
@@ -253,10 +271,14 @@ const ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = (props) => {
253271

254272
return (
255273
<Fragment>
256-
{props.children?.(
257-
dataSource?.slice(startIndex, endIndex + 1),
258-
renderPagination()
259-
)}
274+
<PaginationContext.Provider
275+
value={{ totalPage, pageSize, changePage: handleChange }}
276+
>
277+
{props.children?.(
278+
dataSource?.slice(startIndex, endIndex + 1),
279+
renderPagination()
280+
)}
281+
</PaginationContext.Provider>
260282
</Fragment>
261283
)
262284
}
@@ -357,4 +379,23 @@ ArrayTable.Column = () => {
357379

358380
ArrayBase.mixin(ArrayTable)
359381

382+
const Addition: ArrayBaseMixins['Addition'] = (props) => {
383+
const array = ArrayBase.useArray()
384+
const { totalPage = 0, pageSize = 10, changePage } = usePagination()
385+
return (
386+
<ArrayBase.Addition
387+
{...props}
388+
onClick={(e) => {
389+
// 如果添加数据后将超过当前页,则自动切换到下一页
390+
const total = array?.field?.value.length || 0
391+
if (total === totalPage * pageSize + 1 && isFn(changePage)) {
392+
changePage(totalPage + 1)
393+
}
394+
props.onClick?.(e)
395+
}}
396+
/>
397+
)
398+
}
399+
ArrayTable.Addition = Addition
400+
360401
export default ArrayTable

packages/element/src/array-table/index.ts

+61-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { computed, defineComponent, ref, Ref } from '@vue/composition-api'
1+
import {
2+
computed,
3+
defineComponent,
4+
ref,
5+
Ref,
6+
provide,
7+
inject,
8+
} from '@vue/composition-api'
29
import {
310
GeneralField,
411
IVoidFieldFactoryProps,
@@ -13,7 +20,7 @@ import {
1320
Fragment,
1421
} from '@formily/vue'
1522
import { observer } from '@formily/reactive-vue'
16-
import { isArr, isBool } from '@formily/shared'
23+
import { isArr, isBool, isFn } from '@formily/shared'
1724
import { ArrayBase } from '../array-base'
1825
import { stylePrefix } from '../__builtins__/configs'
1926
import { composeExport } from '../__builtins__/shared'
@@ -65,6 +72,14 @@ type ColumnProps = ElColumnProps & {
6572
}) => VNode
6673
}
6774

75+
interface PaginationAction {
76+
totalPage?: number
77+
pageSize?: number
78+
changePage?: (page: number) => void
79+
}
80+
81+
const PaginationSymbol = Symbol('pagination')
82+
6883
const isColumnComponent = (schema: Schema) => {
6984
return schema['x-component']?.indexOf('Column') > -1
7085
}
@@ -320,6 +335,10 @@ const StatusSelect = observer(
320335
}
321336
)
322337

338+
const usePagination = () => {
339+
return inject<Ref<PaginationAction>>(PaginationSymbol, ref({}))
340+
}
341+
323342
const ArrayTablePagination = defineComponent<IArrayTablePaginationProps>({
324343
inheritAttrs: false,
325344
props: ['pageSize', 'dataSource'],
@@ -396,6 +415,15 @@ const ArrayTablePagination = defineComponent<IArrayTablePaginationProps>({
396415
)
397416
}
398417

418+
const paginationContext = computed<PaginationAction>(() => {
419+
return {
420+
totalPage: totalPage.value,
421+
pageSize: pageSize.value,
422+
changePage: (page: number) => (current.value = page),
423+
}
424+
})
425+
provide(PaginationSymbol, paginationContext)
426+
399427
return () => {
400428
return h(
401429
Fragment,
@@ -556,11 +584,41 @@ const ArrayTableColumn: Component = {
556584
},
557585
}
558586

587+
const ArrayAddition = defineComponent({
588+
name: 'ArrayAddition',
589+
setup(props, { attrs, listeners, slots }) {
590+
const array = ArrayBase.useArray()
591+
const paginationRef = usePagination()
592+
593+
const onClick = listeners['click']
594+
listeners['click'] = (e) => {
595+
const { totalPage = 0, pageSize = 10, changePage } = paginationRef.value
596+
// 如果添加数据后超过当前页,则自动切换到下一页
597+
const total = array?.field?.value?.value.length || 0
598+
if (total === (totalPage - 1) * pageSize + 1 && isFn(changePage)) {
599+
changePage(totalPage)
600+
}
601+
if (onClick) onClick(e)
602+
}
603+
return () => {
604+
return h(
605+
ArrayBase.Addition,
606+
{
607+
props,
608+
attrs,
609+
on: listeners,
610+
},
611+
slots
612+
)
613+
}
614+
},
615+
})
616+
559617
export const ArrayTable = composeExport(ArrayTableInner, {
560618
Column: ArrayTableColumn,
561619
Index: ArrayBase.Index,
562620
SortHandle: ArrayBase.SortHandle,
563-
Addition: ArrayBase.Addition,
621+
Addition: ArrayAddition,
564622
Remove: ArrayBase.Remove,
565623
MoveDown: ArrayBase.MoveDown,
566624
MoveUp: ArrayBase.MoveUp,

packages/next/src/array-table/index.tsx

+47-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import React, { Fragment, useState, useRef, useEffect } from 'react'
1+
import React, {
2+
Fragment,
3+
useState,
4+
useRef,
5+
useEffect,
6+
createContext,
7+
useContext,
8+
} from 'react'
29
import { Table, Pagination, Select, Badge } from '@alifd/next'
310
import { PaginationProps } from '@alifd/next/lib/pagination'
411
import { TableProps, ColumnProps } from '@alifd/next/lib/table'
@@ -12,7 +19,7 @@ import {
1219
RecursionField,
1320
ReactFC,
1421
} from '@formily/react'
15-
import { isArr, isBool } from '@formily/shared'
22+
import { isArr, isBool, isFn } from '@formily/shared'
1623
import { Schema } from '@formily/json-schema'
1724
import { usePrefixCls } from '../__builtins__'
1825
import { ArrayBase, ArrayBaseMixins } from '../array-base'
@@ -46,6 +53,12 @@ type ComposedArrayTable = ReactFC<ExtendTableProps> &
4653
Column?: ReactFC<ColumnProps>
4754
}
4855

56+
interface PaginationAction {
57+
totalPage?: number
58+
pageSize?: number
59+
changePage?: (page: number) => void
60+
}
61+
4962
const isColumnComponent = (schema: Schema) => {
5063
return schema['x-component']?.indexOf('Column') > -1
5164
}
@@ -192,6 +205,11 @@ const StatusSelect: ReactFC<IStatusSelectProps> = observer(
192205
}
193206
)
194207

208+
const PaginationContext = createContext<PaginationAction>({})
209+
const usePagination = () => {
210+
return useContext(PaginationContext)
211+
}
212+
195213
const ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = ({
196214
children,
197215
dataSource,
@@ -249,10 +267,14 @@ const ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = ({
249267

250268
return (
251269
<Fragment>
252-
{children?.(
253-
dataSource?.slice(startIndex, endIndex + 1),
254-
renderPagination()
255-
)}
270+
<PaginationContext.Provider
271+
value={{ totalPage, pageSize, changePage: handleChange }}
272+
>
273+
{children?.(
274+
dataSource?.slice(startIndex, endIndex + 1),
275+
renderPagination()
276+
)}
277+
</PaginationContext.Provider>
256278
</Fragment>
257279
)
258280
}
@@ -316,4 +338,23 @@ ArrayTable.Column = () => {
316338

317339
ArrayBase.mixin(ArrayTable)
318340

341+
const Addition: ArrayBaseMixins['Addition'] = (props) => {
342+
const array = ArrayBase.useArray()
343+
const { totalPage = 0, pageSize = 10, changePage } = usePagination()
344+
return (
345+
<ArrayBase.Addition
346+
{...props}
347+
onClick={(e) => {
348+
// 如果添加数据后将超过当前页,则自动切换到下一页
349+
const total = array?.field?.value.length || 0
350+
if (total === totalPage * pageSize + 1 && isFn(changePage)) {
351+
changePage(totalPage + 1)
352+
}
353+
props.onClick?.(e)
354+
}}
355+
/>
356+
)
357+
}
358+
ArrayTable.Addition = Addition
359+
319360
export default ArrayTable

0 commit comments

Comments
 (0)