antd-table-infinity
Advanced tools
Comparing version 1.1.2 to 1.1.3
@@ -416,2 +416,3 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
forwardedRef: ref | ||
}))); | ||
}))); | ||
export { InfinityTable }; |
@@ -278,3 +278,3 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } | ||
} | ||
}, loading && loadingIndicator, ' '), domNode); | ||
}, loading && loadingIndicator, " "), domNode); | ||
} | ||
@@ -583,3 +583,3 @@ | ||
loadingIndicator: loadingIndicator | ||
}), !this.isInitial && pagination && ['top', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({ | ||
}), total && pagination && ['top', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({ | ||
showQuickJumper: true | ||
@@ -601,3 +601,3 @@ }, pagination, { | ||
className: `infinity-page-table ${rest.className ? rest.className : ''}` | ||
})), !this.isInitial && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({ | ||
})), total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({ | ||
showQuickJumper: true | ||
@@ -679,2 +679,3 @@ }, pagination, { | ||
forwardedRef: ref | ||
}))); | ||
}))); | ||
export { InfinityTable }; |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.default = void 0; | ||
exports.InfinityTable = exports.default = void 0; | ||
@@ -389,2 +389,3 @@ var _react = _interopRequireWildcard(require("react")); | ||
exports.InfinityTable = InfinityTable; | ||
InfinityTable.defaultProps = { | ||
@@ -391,0 +392,0 @@ // loading 效果, A visual react component for Loading status |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.default = void 0; | ||
exports.InfinityTable = exports.default = void 0; | ||
@@ -294,3 +294,3 @@ var _react = _interopRequireWildcard(require("react")); | ||
} | ||
}, loading && loadingIndicator, ' '), domNode); | ||
}, loading && loadingIndicator, " "), domNode); | ||
} | ||
@@ -599,3 +599,3 @@ | ||
loadingIndicator: loadingIndicator | ||
}), !this.isInitial && pagination && ['top', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ | ||
}), total && pagination && ['top', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ | ||
showQuickJumper: true | ||
@@ -617,3 +617,3 @@ }, pagination, { | ||
className: `infinity-page-table ${rest.className ? rest.className : ''}` | ||
})), !this.isInitial && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ | ||
})), total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({ | ||
showQuickJumper: true | ||
@@ -632,2 +632,3 @@ }, pagination, { | ||
exports.InfinityTable = InfinityTable; | ||
InfinityTable.defaultProps = { | ||
@@ -634,0 +635,0 @@ // loading 效果, A visual react component for Loading status |
{ | ||
"name": "antd-table-infinity", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "storybook": "start-storybook -p 9001 -c .storybook", |
@@ -106,2 +106,3 @@ 中文 | [English](./README_en.md) | ||
<Table | ||
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题 | ||
className="custom-classname" | ||
@@ -191,3 +192,3 @@ pagination={{ | ||
<Table | ||
key="key" | ||
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题 | ||
loading={this.state.loading} | ||
@@ -264,3 +265,3 @@ onFetch={this.handleFetch} | ||
<Table | ||
key="key" | ||
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题 | ||
loading={this.state.loading} | ||
@@ -300,2 +301,4 @@ onFetch={this.handleFetch} | ||
- `import 'antd-table-infinity/dist/index.css'`; 包含使用到的antd相关组件的所有css | ||
3. rowKey='key' 非常重要,antd-table需要的每行数据的唯一键值,否则滚动翻页会出问题,实在没有,请用 uuid 库创建 参考:[https://ant.design/components/table-cn/#%E6%B3%A8%E6%84%8F](https://ant.design/components/table-cn/#%E6%B3%A8%E6%84%8F) | ||
@@ -302,0 +305,0 @@ ### 已发现问题 |
@@ -404,1 +404,3 @@ import React, { PureComponent, Fragment } from 'react'; | ||
)); | ||
export { InfinityTable } |
@@ -1,709 +0,594 @@ | ||
import React, { Component, Fragment } from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import { | ||
element, | ||
string, | ||
bool, | ||
number, | ||
array, | ||
object, | ||
func, | ||
oneOfType, | ||
oneOf, | ||
shape, | ||
} from 'prop-types'; | ||
import { Table, Spin, Pagination } from 'antd'; | ||
import throttle from 'lodash.throttle'; | ||
import React, { Component, Fragment } from 'react' | ||
import ReactDOM from 'react-dom' | ||
import { element, string, bool, number, array, object, func, oneOfType, oneOf, shape } from 'prop-types' | ||
import { Table, Spin, Pagination } from 'antd' | ||
import throttle from 'lodash.throttle' | ||
const noop = () => {}; | ||
const noop = () => {} | ||
const fetchDebounce = (() => { | ||
const loading = []; | ||
return ({ page, pageSize, onFetch }) => { | ||
const now = Date.now(); | ||
if (!loading[page] || (loading[page] && now - loading[page] > 1000)) { | ||
onFetch({ page, pageSize }); | ||
} | ||
loading[page] = now; | ||
}; | ||
})(); | ||
const loading = [] | ||
return ({ page, pageSize, onFetch }) => { | ||
const now = Date.now() | ||
if (!loading[page] || (loading[page] && now - loading[page] > 1000)) { | ||
onFetch({ page, pageSize }) | ||
} | ||
loading[page] = now | ||
} | ||
})() | ||
function getCachePage({ | ||
step, | ||
maxPage, | ||
pageSize, | ||
onFetch, | ||
loading, | ||
cacheData, | ||
currentPage, | ||
}) { | ||
const pageBefore = currentPage - step; | ||
const pageAfter = currentPage + step; | ||
const cachePageDataBefore = cacheData[pageBefore]; | ||
const cachePageData = cacheData[currentPage]; | ||
const cachePageDataAfter = cacheData[pageAfter]; | ||
if (!loading) { | ||
!cachePageData && | ||
currentPage > 0 && | ||
currentPage <= maxPage && | ||
fetchDebounce({ page: currentPage, pageSize, onFetch }); | ||
!cachePageDataBefore && | ||
pageBefore > 0 && | ||
pageBefore <= maxPage && | ||
fetchDebounce({ page: pageBefore, pageSize, onFetch }); | ||
!cachePageDataAfter && | ||
pageAfter > 0 && | ||
pageAfter <= maxPage && | ||
fetchDebounce({ page: pageAfter, pageSize, onFetch }); | ||
} | ||
let lastOwnDataPage = currentPage; | ||
if (cachePageDataAfter) { | ||
lastOwnDataPage = pageAfter; | ||
} else if (cachePageData) { | ||
lastOwnDataPage = currentPage; | ||
} else if (cachePageDataBefore) { | ||
lastOwnDataPage = pageBefore; | ||
} | ||
function getCachePage({ step, maxPage, pageSize, onFetch, loading, cacheData, currentPage }) { | ||
const pageBefore = currentPage - step | ||
const pageAfter = currentPage + step | ||
const cachePageDataBefore = cacheData[pageBefore] | ||
const cachePageData = cacheData[currentPage] | ||
const cachePageDataAfter = cacheData[pageAfter] | ||
if (!loading) { | ||
!cachePageData && | ||
currentPage > 0 && | ||
currentPage <= maxPage && | ||
fetchDebounce({ page: currentPage, pageSize, onFetch }) | ||
!cachePageDataBefore && | ||
pageBefore > 0 && | ||
pageBefore <= maxPage && | ||
fetchDebounce({ page: pageBefore, pageSize, onFetch }) | ||
!cachePageDataAfter && | ||
pageAfter > 0 && | ||
pageAfter <= maxPage && | ||
fetchDebounce({ page: pageAfter, pageSize, onFetch }) | ||
} | ||
let lastOwnDataPage = currentPage | ||
if (cachePageDataAfter) { | ||
lastOwnDataPage = pageAfter | ||
} else if (cachePageData) { | ||
lastOwnDataPage = currentPage | ||
} else if (cachePageDataBefore) { | ||
lastOwnDataPage = pageBefore | ||
} | ||
return [ | ||
cachePageDataBefore || [], | ||
cachePageData || [], | ||
cachePageDataAfter || [], | ||
lastOwnDataPage, | ||
]; | ||
return [cachePageDataBefore || [], cachePageData || [], cachePageDataAfter || [], lastOwnDataPage] | ||
} | ||
const computeState = ( | ||
{ | ||
pageSize, | ||
onFetch, | ||
loading, | ||
total, | ||
bidirectionalCachePages: cachePages, | ||
dataSource: [page, data], | ||
}, | ||
{ maxPage, currentPage, cacheData, rowHeight }, | ||
{ pageSize, onFetch, loading, total, bidirectionalCachePages: cachePages, dataSource: [page, data] }, | ||
{ maxPage, currentPage, cacheData, rowHeight }, | ||
) => { | ||
let bidirectionalCachePages = cachePages; | ||
let newCacheData = cacheData; | ||
let bidirectionalCachePages = cachePages | ||
let newCacheData = cacheData | ||
if (cachePages < 1) { | ||
bidirectionalCachePages = 1; | ||
} | ||
if (bidirectionalCachePages * 2 + 1 < maxPage) { | ||
let startPage = currentPage - bidirectionalCachePages; | ||
startPage = startPage < 1 ? 1 : startPage; | ||
if (cachePages < 1) { | ||
bidirectionalCachePages = 1 | ||
} | ||
if (bidirectionalCachePages * 2 + 1 < maxPage) { | ||
let startPage = currentPage - bidirectionalCachePages | ||
startPage = startPage < 1 ? 1 : startPage | ||
let endPage = currentPage + bidirectionalCachePages; | ||
endPage = endPage > maxPage ? maxPage : endPage; | ||
let endPage = currentPage + bidirectionalCachePages | ||
endPage = endPage > maxPage ? maxPage : endPage | ||
cacheData[page] = data; // eslint-disable-line | ||
newCacheData = Array.from({ length: maxPage }); | ||
cacheData[page] = data // eslint-disable-line | ||
newCacheData = Array.from({ length: maxPage }) | ||
Array.prototype.splice.apply( | ||
newCacheData, | ||
[startPage, endPage - startPage + 1].concat( | ||
cacheData.slice(startPage, endPage + 1), | ||
), | ||
); | ||
} | ||
newCacheData[page] = data; | ||
Array.prototype.splice.apply( | ||
newCacheData, | ||
[startPage, endPage - startPage + 1].concat(cacheData.slice(startPage, endPage + 1)), | ||
) | ||
} | ||
newCacheData[page] = data | ||
const [ | ||
cachePageDataBefore, | ||
cachePageData, | ||
cachePageDataAfter, | ||
lastOwnDataPage, | ||
] = getCachePage({ | ||
step: 1, | ||
maxPage, | ||
pageSize, | ||
onFetch, | ||
loading, | ||
cacheData: newCacheData, | ||
currentPage, | ||
}); | ||
const [cachePageDataBefore, cachePageData, cachePageDataAfter, lastOwnDataPage] = getCachePage({ | ||
step: 1, | ||
maxPage, | ||
pageSize, | ||
onFetch, | ||
loading, | ||
cacheData: newCacheData, | ||
currentPage, | ||
}) | ||
const upperHeight = Math.round( | ||
(currentPage - 1 - (cachePageDataBefore.length ? 1 : 0)) * | ||
pageSize * | ||
rowHeight, | ||
); | ||
const upperHeight = Math.round((currentPage - 1 - (cachePageDataBefore.length ? 1 : 0)) * pageSize * rowHeight) | ||
const underHeight = Math.round( | ||
// 已经是最后一页,直接返回0,否则如果有零头total % pageSize,需要加上不满一个page的零头lastOwnDataPageLength,但需要少加一个整页pageSize | ||
maxPage === lastOwnDataPage | ||
? 0 | ||
: ((maxPage - lastOwnDataPage) * pageSize + (total % pageSize)) * | ||
rowHeight, | ||
); | ||
const dataSource = cachePageDataBefore | ||
.concat(cachePageData) | ||
.concat(cachePageDataAfter); | ||
const underHeight = Math.round( | ||
// 已经是最后一页,直接返回0,否则如果有零头total % pageSize,需要加上不满一个page的零头lastOwnDataPageLength,但需要少加一个整页pageSize | ||
maxPage === lastOwnDataPage ? 0 : ((maxPage - lastOwnDataPage) * pageSize + (total % pageSize)) * rowHeight, | ||
) | ||
const dataSource = cachePageDataBefore.concat(cachePageData).concat(cachePageDataAfter) | ||
return { | ||
hasCacheBefore: !!cachePageDataBefore.length, | ||
hasCache: !!cachePageData.length, | ||
hasCacheAfter: !!cachePageDataAfter.length, | ||
cacheData: newCacheData, | ||
dataSource, | ||
underHeight, | ||
upperHeight, | ||
}; | ||
}; | ||
return { | ||
hasCacheBefore: !!cachePageDataBefore.length, | ||
hasCache: !!cachePageData.length, | ||
hasCacheAfter: !!cachePageDataAfter.length, | ||
cacheData: newCacheData, | ||
dataSource, | ||
underHeight, | ||
upperHeight, | ||
} | ||
} | ||
/* eslint-disable react/no-redundant-should-component-update */ | ||
class InfinityTable extends Component { | ||
static PlaceHolder({ height, domNode, loading, loadingIndicator }) { | ||
return ( | ||
domNode && | ||
ReactDOM.createPortal( | ||
<div style={{ height: `${height}px` }}> | ||
{loading && loadingIndicator}{' '} | ||
</div>, | ||
domNode, | ||
) | ||
); | ||
} | ||
static LoadingPlaceHolder({ domNode, loading, loadingIndicator }) { | ||
return ( | ||
domNode && | ||
ReactDOM.createPortal(loading ? loadingIndicator : <div />, domNode) | ||
); | ||
} | ||
state = { | ||
scrollTop: 0, // 滚动条位置 | ||
dataSource: [], // DOM上显示的数据 | ||
rowHeight: 0, // 每行的实际高度 | ||
cacheData: [], // 缓存的数据集大小 | ||
currentPage: 1, // 当前页位置 | ||
underHeight: 0, // 下撑高 | ||
upperHeight: 0, // 上撑高 | ||
}; | ||
static getDerivedStateFromProps(props, prevState) { | ||
return computeState(props, prevState); | ||
} | ||
static PlaceHolder({ height, domNode, loading, loadingIndicator }) { | ||
return ( | ||
domNode && | ||
ReactDOM.createPortal(<div style={{ height: `${height}px` }}>{loading && loadingIndicator} </div>, domNode) | ||
) | ||
} | ||
static LoadingPlaceHolder({ domNode, loading, loadingIndicator }) { | ||
return domNode && ReactDOM.createPortal(loading ? loadingIndicator : <div />, domNode) | ||
} | ||
state = { | ||
scrollTop: 0, // 滚动条位置 | ||
dataSource: [], // DOM上显示的数据 | ||
rowHeight: 0, // 每行的实际高度 | ||
cacheData: [], // 缓存的数据集大小 | ||
currentPage: 1, // 当前页位置 | ||
underHeight: 0, // 下撑高 | ||
upperHeight: 0, // 上撑高 | ||
} | ||
static getDerivedStateFromProps(props, prevState) { | ||
return computeState(props, prevState) | ||
} | ||
componentDidMount() { | ||
/* eslint-disable */ | ||
this.refRoot = ReactDOM.findDOMNode(this); | ||
this.refScroll = this.refRoot.getElementsByClassName('ant-table-body')[0]; | ||
this.refTable = this.refScroll.getElementsByTagName('tbody')[0]; | ||
/* eslint-enabled */ | ||
this.createUnderPlaceholder(); | ||
this.createUpperPlaceholder(); | ||
this.setStateWithThrottle = throttle(this.updateTable, 0); | ||
this.props.onScroll && | ||
this.refScroll.addEventListener('scroll', this.props.onScroll); | ||
componentDidMount() { | ||
/* eslint-disable */ | ||
this.refRoot = ReactDOM.findDOMNode(this) | ||
this.refScroll = this.refRoot.getElementsByClassName('ant-table-body')[0] | ||
this.refTable = this.refScroll.getElementsByTagName('tbody')[0] | ||
/* eslint-enabled */ | ||
this.createUnderPlaceholder() | ||
this.createUpperPlaceholder() | ||
this.setStateWithThrottle = throttle(this.updateTable, 0) | ||
this.props.onScroll && this.refScroll.addEventListener('scroll', this.props.onScroll) | ||
if (this.refScroll) { | ||
this.io = new IntersectionObserver( | ||
changes => { | ||
const { debug } = this.props; | ||
let shouldUpdate = true; | ||
this.ioTargetState = changes.reduce((result, change) => { | ||
const ret = { ...result }; | ||
switch (change.target) { | ||
case this.refPageBoundaryBefore: | ||
ret.refPageBoundaryBefore = change; | ||
// Bug fix: | ||
// 向下滚动的时候,如果边界第一行数据触发,不需要更新视图,因为上一页的最后一行已经触发了视图更新, | ||
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 | ||
if ( | ||
!this.isPaginationClick && | ||
changes.length === 1 && | ||
this.state.direction === 'down' | ||
) { | ||
shouldUpdate = false; | ||
} | ||
if (this.refScroll) { | ||
this.io = new IntersectionObserver( | ||
changes => { | ||
const { debug } = this.props | ||
let shouldUpdate = true | ||
this.ioTargetState = changes.reduce((result, change) => { | ||
const ret = { ...result } | ||
switch (change.target) { | ||
case this.refPageBoundaryBefore: | ||
ret.refPageBoundaryBefore = change | ||
// Bug fix: | ||
// 向下滚动的时候,如果边界第一行数据触发,不需要更新视图,因为上一页的最后一行已经触发了视图更新, | ||
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 | ||
if ( | ||
!this.isPaginationClick && | ||
changes.length === 1 && | ||
this.state.direction === 'down' | ||
) { | ||
shouldUpdate = false | ||
} | ||
break; | ||
case this.refPageBoundaryAfter: | ||
ret.refPageBoundaryAfter = change; | ||
// Bug fix: | ||
// 向上滚动的时候,如果边界最后行数据触发,不需要更新视图,因为上一页的第一行已经触发了视图更新 | ||
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 | ||
if ( | ||
!this.isPaginationClick && | ||
changes.length === 1 && | ||
this.state.direction === 'up' | ||
) { | ||
shouldUpdate = false; | ||
} | ||
break; | ||
default: // console.log(change) | ||
} | ||
return ret; | ||
}, this.ioTargetState); | ||
break | ||
case this.refPageBoundaryAfter: | ||
ret.refPageBoundaryAfter = change | ||
// Bug fix: | ||
// 向上滚动的时候,如果边界最后行数据触发,不需要更新视图,因为上一页的第一行已经触发了视图更新 | ||
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码 | ||
if (!this.isPaginationClick && changes.length === 1 && this.state.direction === 'up') { | ||
shouldUpdate = false | ||
} | ||
break | ||
default: // console.log(change) | ||
} | ||
return ret | ||
}, this.ioTargetState) | ||
this.isPaginationClick = false; | ||
this.isPaginationClick = false | ||
debug && | ||
console.log('shouldUpdate:IntersectionObserver', { | ||
shouldUpdate, | ||
changes, | ||
}); | ||
debug && | ||
console.log('shouldUpdate:IntersectionObserver', { | ||
shouldUpdate, | ||
changes, | ||
}) | ||
shouldUpdate && this.setStateWithThrottle(); | ||
}, | ||
{ | ||
root: this.refScroll, | ||
threshold: [0, 1], | ||
}, | ||
); | ||
this.toggleObserver(); | ||
} | ||
shouldUpdate && this.setStateWithThrottle() | ||
}, | ||
{ | ||
root: this.refScroll, | ||
threshold: [0, 1], | ||
}, | ||
) | ||
this.toggleObserver() | ||
} | ||
this.props.onFetch({ page: 1, pageSize: this.props.pageSize }); | ||
this.props.onFetch({ page: 1, pageSize: this.props.pageSize }) | ||
new Promise(reslove => { | ||
this.initialReslove = reslove; | ||
}).then(() => { | ||
const { | ||
pageSize, | ||
pagination: { defaultCurrent = 1 }, | ||
} = this.props; | ||
this.createLoadingPlaceholder(); // fullLoading | ||
this.scrollToPage(defaultCurrent); | ||
const visibleRowCount = Math.round( | ||
this.refScroll.clientHeight / this.state.rowHeight, | ||
); | ||
this.isReady = true; | ||
if (pageSize < visibleRowCount) { | ||
console.warn( | ||
`pagesize(${pageSize}) less than visible row count(${visibleRowCount}), maybe you set error!`, | ||
); | ||
} | ||
}); | ||
} | ||
shouldComponentUpdate(nextProps, nextState) { | ||
const { pageSize, debug } = nextProps; | ||
const { | ||
maxPage, | ||
currentPage, | ||
dataSource, | ||
direction, | ||
rowHeight, | ||
} = nextState; | ||
let shouldUpdate = true; | ||
new Promise(reslove => { | ||
this.initialReslove = reslove | ||
}).then(() => { | ||
const { | ||
pageSize, | ||
pagination: { defaultCurrent = 1 }, | ||
} = this.props | ||
this.createLoadingPlaceholder() // fullLoading | ||
this.scrollToPage(defaultCurrent) | ||
const visibleRowCount = Math.round(this.refScroll.clientHeight / this.state.rowHeight) | ||
this.isReady = true | ||
if (pageSize < visibleRowCount) { | ||
console.warn( | ||
`pagesize(${pageSize}) less than visible row count(${visibleRowCount}), maybe you set error!`, | ||
) | ||
} | ||
}) | ||
} | ||
shouldComponentUpdate(nextProps, nextState) { | ||
const { pageSize, debug } = nextProps | ||
const { maxPage, currentPage, dataSource, direction, rowHeight } = nextState | ||
let shouldUpdate = true | ||
// 有且仅有当前页上下边界同时触发时,表示更换边界,不需要更新 | ||
if (this.isPageBoundary) { | ||
shouldUpdate = false; | ||
this.isPageBoundary = false; | ||
} | ||
debug && console.log('shouldUpdate:updateBoundary', { shouldUpdate }); | ||
// 有且仅有当前页上下边界同时触发时,表示更换边界,不需要更新 | ||
if (this.isPageBoundary) { | ||
shouldUpdate = false | ||
this.isPageBoundary = false | ||
} | ||
debug && console.log('shouldUpdate:updateBoundary', { shouldUpdate }) | ||
if (shouldUpdate && !this.isInitial) { | ||
let currentPageReal = currentPage; | ||
if (shouldUpdate && !this.isInitial) { | ||
let currentPageReal = currentPage | ||
// 由于state中的currentPage延迟与真实的currentPage不一致,当出现这种情况时,强制updateTable() | ||
currentPageReal = | ||
Math.floor(this.refScroll.scrollTop / (pageSize * rowHeight)) + 1 || 1; | ||
currentPageReal = currentPageReal > maxPage ? maxPage : currentPageReal; | ||
if (currentPageReal !== currentPage) { | ||
this.updateTable(); | ||
shouldUpdate = false; | ||
} | ||
// 由于state中的currentPage延迟与真实的currentPage不一致,当出现这种情况时,强制updateTable() | ||
currentPageReal = Math.floor(this.refScroll.scrollTop / (pageSize * rowHeight)) + 1 || 1 | ||
currentPageReal = currentPageReal > maxPage ? maxPage : currentPageReal | ||
if (currentPageReal !== currentPage) { | ||
this.updateTable() | ||
shouldUpdate = false | ||
} | ||
debug && | ||
console.log('shouldUpdate:currentPageReal', { | ||
currentPageReal, | ||
currentPage, | ||
shouldUpdate, | ||
}); | ||
} | ||
debug && | ||
console.log('shouldUpdate:currentPageReal', { | ||
currentPageReal, | ||
currentPage, | ||
shouldUpdate, | ||
}) | ||
} | ||
if (shouldUpdate) { | ||
const { | ||
refPageBoundaryBefore, | ||
refPageBoundaryAfter, | ||
} = this.ioTargetState; | ||
if (shouldUpdate) { | ||
const { refPageBoundaryBefore, refPageBoundaryAfter } = this.ioTargetState | ||
switch (direction) { | ||
case 'up': | ||
if ( | ||
this.state.hasCacheAfter && | ||
currentPage < maxPage - 2 && // Bug fix: 如果是最后三页向后点击切换,需要刷新视图,否则页码表记停留在前一页 | ||
refPageBoundaryBefore && | ||
refPageBoundaryBefore.intersectionRatio > 0 | ||
) | ||
shouldUpdate = false; | ||
break; | ||
switch (direction) { | ||
case 'up': | ||
if ( | ||
this.state.hasCacheAfter && | ||
currentPage < maxPage - 2 && // Bug fix: 如果是最后三页向后点击切换,需要刷新视图,否则页码表记停留在前一页 | ||
refPageBoundaryBefore && | ||
refPageBoundaryBefore.intersectionRatio > 0 | ||
) | ||
shouldUpdate = false | ||
break | ||
case 'down': | ||
if ( | ||
this.state.currentPage === currentPage && | ||
this.state.hasCacheAfter && // Bug fix: 可能存在3页数据已经加载到了, 但之前没有刷新的情况,所以需要刷新,判断特征是之前的数据小于3页 | ||
refPageBoundaryAfter && | ||
refPageBoundaryAfter.intersectionRatio > 0 | ||
) | ||
shouldUpdate = false; | ||
} | ||
case 'down': | ||
if ( | ||
this.state.currentPage === currentPage && | ||
this.state.hasCacheAfter && // Bug fix: 可能存在3页数据已经加载到了, 但之前没有刷新的情况,所以需要刷新,判断特征是之前的数据小于3页 | ||
refPageBoundaryAfter && | ||
refPageBoundaryAfter.intersectionRatio > 0 | ||
) | ||
shouldUpdate = false | ||
} | ||
debug && | ||
console.log('shouldUpdate:verboseBoundary', { | ||
shouldUpdate, | ||
direction, | ||
dataSource, | ||
Before: | ||
refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio, | ||
After: refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio, | ||
}); | ||
} | ||
debug && | ||
console.log('shouldUpdate:verboseBoundary', { | ||
shouldUpdate, | ||
direction, | ||
dataSource, | ||
Before: refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio, | ||
After: refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio, | ||
}) | ||
} | ||
if (shouldUpdate) { | ||
shouldUpdate = [1, maxPage, maxPage - 1, maxPage - 2].includes( | ||
currentPage, | ||
) | ||
? dataSource.length > 0 | ||
: [ | ||
// 如果已经加载3页数据,需要更新视图,否则不在 fullLoading 状态,即使数据不满3页也需要更新视图 | ||
...(this.fullLoading ? [] : [0, pageSize, pageSize * 2]), | ||
pageSize * 3, | ||
].includes(dataSource.length); | ||
if (shouldUpdate) { | ||
shouldUpdate = [1, maxPage, maxPage - 1, maxPage - 2].includes(currentPage) | ||
? dataSource.length > 0 | ||
: [ | ||
// 如果已经加载3页数据,需要更新视图,否则不在 fullLoading 状态,即使数据不满3页也需要更新视图 | ||
...(this.fullLoading ? [] : [0, pageSize, pageSize * 2]), | ||
pageSize * 3, | ||
].includes(dataSource.length) | ||
debug && | ||
console.log('shouldUpdate:3Page', { | ||
currentPage, | ||
dataSource, | ||
shouldUpdate, | ||
state: this.state, | ||
nextState, | ||
}); | ||
} | ||
debug && | ||
console.log('shouldUpdate:3Page', { | ||
currentPage, | ||
dataSource, | ||
shouldUpdate, | ||
state: this.state, | ||
nextState, | ||
}) | ||
} | ||
return shouldUpdate; | ||
} | ||
componentDidUpdate(preProps, preState) { | ||
const { | ||
hasCache, | ||
hasCacheBefore, | ||
currentPage, | ||
dataSource, | ||
maxPage, | ||
} = this.state; | ||
const { pageSize, debug } = this.props; | ||
return shouldUpdate | ||
} | ||
componentDidUpdate(preProps, preState) { | ||
const { hasCache, hasCacheBefore, currentPage, dataSource, maxPage } = this.state | ||
const { pageSize, debug } = this.props | ||
if (!this.isInitial) { | ||
let before, after; | ||
if (!this.isInitial) { | ||
let before, after | ||
if (hasCache && hasCacheBefore) { | ||
if (currentPage === 1 || currentPage === maxPage - 1) { | ||
before = 0; | ||
after = pageSize - 1; | ||
} else if (currentPage === maxPage) { | ||
before = 0; | ||
after = dataSource.length - 1; | ||
} else { | ||
before = pageSize; | ||
after = pageSize * 2 - 1; | ||
} | ||
if (hasCache && hasCacheBefore) { | ||
if (currentPage === 1 || currentPage === maxPage - 1) { | ||
before = 0 | ||
after = pageSize - 1 | ||
} else if (currentPage === maxPage) { | ||
before = 0 | ||
after = dataSource.length - 1 | ||
} else { | ||
before = pageSize | ||
after = pageSize * 2 - 1 | ||
} | ||
if (this.refPageBoundaryBefore !== this.refTable.children[before]) { | ||
this.refPageBoundaryBefore && | ||
this.io.unobserve(this.refPageBoundaryBefore); | ||
this.refPageBoundaryAfter && | ||
this.io.unobserve(this.refPageBoundaryAfter); | ||
if (this.refPageBoundaryBefore !== this.refTable.children[before]) { | ||
this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore) | ||
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter) | ||
this.refPageBoundaryBefore = this.refTable.children[before]; | ||
this.refPageBoundaryAfter = this.refTable.children[after]; | ||
this.refPageBoundaryBefore = this.refTable.children[before] | ||
this.refPageBoundaryAfter = this.refTable.children[after] | ||
this.refPageBoundaryAfter && | ||
this.io.observe(this.refPageBoundaryAfter); | ||
this.refPageBoundaryBefore && | ||
this.io.observe(this.refPageBoundaryBefore); | ||
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter) | ||
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore) | ||
debug && | ||
this.refPageBoundaryBefore && | ||
console.log( | ||
'componentDidUpdate', | ||
this.refPageBoundaryBefore.innerText, | ||
); | ||
debug && | ||
this.refPageBoundaryAfter && | ||
console.log( | ||
'componentDidUpdate', | ||
this.refPageBoundaryAfter.innerText, | ||
); | ||
debug && | ||
this.refPageBoundaryBefore && | ||
console.log('componentDidUpdate', this.refPageBoundaryBefore.innerText) | ||
debug && | ||
this.refPageBoundaryAfter && | ||
console.log('componentDidUpdate', this.refPageBoundaryAfter.innerText) | ||
this.isPageBoundary = true; | ||
} | ||
} | ||
const emptyPlaceholder = this.refRoot.querySelector( | ||
'.ant-table-placeholder', | ||
); | ||
emptyPlaceholder && (emptyPlaceholder.style.display = 'none'); | ||
} | ||
} | ||
componentWillUnmount() { | ||
this.props.onScroll && | ||
this.refScroll.removeEventListener('scroll', this.props.onScroll); | ||
this.io.disconnect(); | ||
} | ||
isInitial = true; // 初始状态,未渲染任何数据 | ||
isReady = false; // 已渲染首屏数据,可交互的状态 | ||
isPageBoundary = false; // 当前页,上下边界更新 | ||
isPaginationClick = false; | ||
refUpperPlaceholder = null; | ||
refUnderPlaceholder = null; | ||
refLoadingPlaceholder = null; | ||
refScroll = null; | ||
refTable = null; | ||
refFooter = null; | ||
refPageBoundaryBefore = null; // 当前页的第一条DOM数据 | ||
refPageBoundaryAfter = null; // 当前页的最后一条DOM数据 | ||
ioTargetState = { | ||
refUnderPlaceholder: null, | ||
refUpperPlaceholder: null, | ||
refTable: null, | ||
refPageBoundaryBefore: null, | ||
refPageBoundaryAfter: null, | ||
}; | ||
createLoadingPlaceholder() { | ||
const refLoadingPlaceholder = document.createElement('div'); | ||
refLoadingPlaceholder.setAttribute('id', 'refLoadingPlaceholder'); | ||
const clientRect = this.refScroll.getBoundingClientRect(); | ||
refLoadingPlaceholder.setAttribute( | ||
'style', | ||
`position:fixed; width:${clientRect.width}px; height:${ | ||
clientRect.height | ||
}px`, | ||
); | ||
this.isPageBoundary = true | ||
} | ||
} | ||
const emptyPlaceholder = this.refRoot.querySelector('.ant-table-placeholder') | ||
emptyPlaceholder && (emptyPlaceholder.style.display = 'none') | ||
} | ||
} | ||
componentWillUnmount() { | ||
this.props.onScroll && this.refScroll.removeEventListener('scroll', this.props.onScroll) | ||
this.io.disconnect() | ||
} | ||
isInitial = true // 初始状态,未渲染任何数据 | ||
isReady = false // 已渲染首屏数据,可交互的状态 | ||
isPageBoundary = false // 当前页,上下边界更新 | ||
isPaginationClick = false | ||
refUpperPlaceholder = null | ||
refUnderPlaceholder = null | ||
refLoadingPlaceholder = null | ||
refScroll = null | ||
refTable = null | ||
refFooter = null | ||
refPageBoundaryBefore = null // 当前页的第一条DOM数据 | ||
refPageBoundaryAfter = null // 当前页的最后一条DOM数据 | ||
ioTargetState = { | ||
refUnderPlaceholder: null, | ||
refUpperPlaceholder: null, | ||
refTable: null, | ||
refPageBoundaryBefore: null, | ||
refPageBoundaryAfter: null, | ||
} | ||
createLoadingPlaceholder() { | ||
const refLoadingPlaceholder = document.createElement('div') | ||
refLoadingPlaceholder.setAttribute('id', 'refLoadingPlaceholder') | ||
const clientRect = this.refScroll.getBoundingClientRect() | ||
refLoadingPlaceholder.setAttribute( | ||
'style', | ||
`position:fixed; width:${clientRect.width}px; height:${clientRect.height}px`, | ||
) | ||
this.refScroll.insertBefore( | ||
refLoadingPlaceholder, | ||
this.refScroll.firstChild, | ||
); | ||
this.refLoadingPlaceholder = refLoadingPlaceholder; | ||
} | ||
this.refScroll.insertBefore(refLoadingPlaceholder, this.refScroll.firstChild) | ||
this.refLoadingPlaceholder = refLoadingPlaceholder | ||
} | ||
// 创建底部填充块 | ||
createUnderPlaceholder() { | ||
const refUnderPlaceholder = document.createElement('div'); | ||
refUnderPlaceholder.setAttribute('id', 'refUnderPlaceholder'); | ||
this.refScroll.appendChild(refUnderPlaceholder); | ||
this.refUnderPlaceholder = refUnderPlaceholder; | ||
} | ||
// 创建顶部填充块 | ||
createUpperPlaceholder() { | ||
const refUpperPlaceholder = document.createElement('div'); | ||
refUpperPlaceholder.setAttribute('id', 'refUpperPlaceholder'); | ||
this.refScroll.insertBefore(refUpperPlaceholder, this.refScroll.firstChild); | ||
this.refUpperPlaceholder = refUpperPlaceholder; | ||
} | ||
// 创建底部填充块 | ||
createUnderPlaceholder() { | ||
const refUnderPlaceholder = document.createElement('div') | ||
refUnderPlaceholder.setAttribute('id', 'refUnderPlaceholder') | ||
this.refScroll.appendChild(refUnderPlaceholder) | ||
this.refUnderPlaceholder = refUnderPlaceholder | ||
} | ||
// 创建顶部填充块 | ||
createUpperPlaceholder() { | ||
const refUpperPlaceholder = document.createElement('div') | ||
refUpperPlaceholder.setAttribute('id', 'refUpperPlaceholder') | ||
this.refScroll.insertBefore(refUpperPlaceholder, this.refScroll.firstChild) | ||
this.refUpperPlaceholder = refUpperPlaceholder | ||
} | ||
scrollToPage = (...args) => { | ||
const { pageSize } = this.props; | ||
const { rowHeight } = this.state; | ||
const [page] = args; | ||
this.refScroll.scrollTop = (page - 1) * pageSize * rowHeight + 1; // Bug fix: + 1个像素,点击页码向后翻页时存在少一个像素就变成上一页的bug | ||
this.isPaginationClick = true; | ||
this.props.pagination && | ||
this.props.pagination.onChange && | ||
this.props.pagination.onChange(...args); | ||
}; | ||
updateTable = () => { | ||
const { clientHeight: tableHeight } = this.refTable; | ||
const { scrollTop } = this.refScroll; | ||
let { rowHeight, maxPage } = this.state; | ||
const { pageSize, total, debug } = this.props; | ||
scrollToPage = (...args) => { | ||
const { pageSize } = this.props | ||
const { rowHeight } = this.state | ||
const [page] = args | ||
this.refScroll.scrollTop = (page - 1) * pageSize * rowHeight + 1 // Bug fix: + 1个像素,点击页码向后翻页时存在少一个像素就变成上一页的bug | ||
this.isPaginationClick = true | ||
this.props.pagination && this.props.pagination.onChange && this.props.pagination.onChange(...args) | ||
} | ||
updateTable = () => { | ||
const { clientHeight: tableHeight } = this.refTable | ||
const { scrollTop } = this.refScroll | ||
let { rowHeight, maxPage } = this.state | ||
const { pageSize, total, debug } = this.props | ||
if (this.isInitial) { | ||
// 还在初始状态 | ||
maxPage = Math.ceil(total / pageSize); | ||
const { | ||
dataSource: { length }, | ||
} = this.state; | ||
rowHeight = tableHeight / length; | ||
if (rowHeight) { | ||
// 当行高出现,表示初次呈现数据数时 | ||
this.isInitial = false; | ||
this.initialReslove(); | ||
} | ||
} | ||
let currentPage = Math.floor(scrollTop / (pageSize * rowHeight)) + 1 || 1; | ||
currentPage = currentPage > maxPage ? maxPage : currentPage; | ||
if (this.isInitial) { | ||
// 还在初始状态 | ||
maxPage = Math.ceil(total / pageSize) | ||
const { | ||
dataSource: { length }, | ||
} = this.state | ||
rowHeight = tableHeight / length | ||
if (rowHeight) { | ||
// 当行高出现,表示初次呈现数据数时 | ||
this.isInitial = false | ||
this.initialReslove() | ||
} | ||
} | ||
let currentPage = Math.floor(scrollTop / (pageSize * rowHeight)) + 1 || 1 | ||
currentPage = currentPage > maxPage ? maxPage : currentPage | ||
debug && | ||
console.log('updateTable', { | ||
currentPage, | ||
}); | ||
this.setState( | ||
{ | ||
direction: | ||
this.refScroll.scrollTop - this.state.scrollTop < 0 ? 'up' : 'down', | ||
scrollTop: this.refScroll.scrollTop, | ||
maxPage, | ||
currentPage, | ||
rowHeight, | ||
}, | ||
// () => console.log('computeState done', this.state), | ||
); | ||
}; | ||
toggleObserver(condition = true) { | ||
if (condition) { | ||
this.io.observe(this.refUpperPlaceholder); | ||
this.io.observe(this.refUnderPlaceholder); | ||
this.io.observe(this.refTable); | ||
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore); | ||
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter); | ||
} else { | ||
this.io.unobserve(this.refUpperPlaceholder); | ||
this.io.unobserve(this.refUnderPlaceholder); | ||
this.io.unobserve(this.refTable); | ||
this.refPageBoundaryBefore && | ||
this.io.unobserve(this.refPageBoundaryBefore); | ||
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter); | ||
} | ||
} | ||
render() { | ||
const { | ||
pageSize, | ||
loadingIndicator, | ||
loading, | ||
total, | ||
columns, | ||
debug, | ||
forwardedRef, | ||
pagination, | ||
...rest | ||
} = this.props; | ||
debug && | ||
console.log('updateTable', { | ||
currentPage, | ||
}) | ||
this.setState( | ||
{ | ||
direction: this.refScroll.scrollTop - this.state.scrollTop < 0 ? 'up' : 'down', | ||
scrollTop: this.refScroll.scrollTop, | ||
maxPage, | ||
currentPage, | ||
rowHeight, | ||
}, | ||
// () => console.log('computeState done', this.state), | ||
) | ||
} | ||
toggleObserver(condition = true) { | ||
if (condition) { | ||
this.io.observe(this.refUpperPlaceholder) | ||
this.io.observe(this.refUnderPlaceholder) | ||
this.io.observe(this.refTable) | ||
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore) | ||
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter) | ||
} else { | ||
this.io.unobserve(this.refUpperPlaceholder) | ||
this.io.unobserve(this.refUnderPlaceholder) | ||
this.io.unobserve(this.refTable) | ||
this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore) | ||
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter) | ||
} | ||
} | ||
render() { | ||
const { | ||
pageSize, | ||
loadingIndicator, | ||
loading, | ||
total, | ||
columns, | ||
debug, | ||
forwardedRef, | ||
pagination, | ||
...rest | ||
} = this.props | ||
const { | ||
dataSource, | ||
upperHeight, | ||
underHeight, | ||
cacheData, | ||
currentPage, | ||
} = this.state; | ||
const { dataSource, upperHeight, underHeight, cacheData, currentPage } = this.state | ||
this.fullLoading = !cacheData[currentPage]; | ||
const { fullLoading } = this; | ||
debug && console.log('%c Rendering', 'color:#f00;font-weight:bold'); | ||
this.fullLoading = !cacheData[currentPage] | ||
const { fullLoading } = this | ||
debug && console.log('%c Rendering', 'color:#f00;font-weight:bold') | ||
return ( | ||
<Fragment> | ||
<InfinityTable.LoadingPlaceHolder | ||
domNode={this.refLoadingPlaceholder} | ||
loading={fullLoading} | ||
loadingIndicator={<Spin tip="Loading..." />} | ||
/> | ||
<InfinityTable.PlaceHolder | ||
height={upperHeight} | ||
domNode={this.refUpperPlaceholder} | ||
loading={loading && !fullLoading} | ||
loadingIndicator={loadingIndicator} | ||
/> | ||
<InfinityTable.PlaceHolder | ||
height={underHeight} | ||
domNode={this.refUnderPlaceholder} | ||
loading={loading && !fullLoading} | ||
loadingIndicator={loadingIndicator} | ||
/> | ||
{!this.isInitial && | ||
pagination && | ||
['top', 'both'].includes(pagination.position) && ( | ||
<Pagination | ||
showQuickJumper | ||
{...pagination} | ||
onChange={this.scrollToPage} | ||
current={currentPage} | ||
pageSize={pageSize} | ||
showSizeChanger={false} | ||
total={total} | ||
className={`infinity-page-table-pagination ${ | ||
pagination && pagination.className ? pagination.className : '' | ||
}`} | ||
/> | ||
)} | ||
<Table | ||
rowKey={record => record.key} | ||
{...rest} | ||
ref={forwardedRef} | ||
columns={columns} | ||
dataSource={dataSource} | ||
pagination={false} | ||
className={`infinity-page-table ${ | ||
rest.className ? rest.className : '' | ||
}`} | ||
/> | ||
{!this.isInitial && | ||
pagination && | ||
[undefined, 'bottom', 'both'].includes(pagination.position) && ( | ||
<Pagination | ||
showQuickJumper | ||
{...pagination} | ||
onChange={this.scrollToPage} | ||
current={currentPage} | ||
pageSize={pageSize} | ||
showSizeChanger={false} | ||
total={total} | ||
className={`infinity-page-table-pagination ${ | ||
pagination && pagination.className ? pagination.className : '' | ||
}`} | ||
/> | ||
)} | ||
</Fragment> | ||
); | ||
} | ||
return ( | ||
<Fragment> | ||
<InfinityTable.LoadingPlaceHolder | ||
domNode={this.refLoadingPlaceholder} | ||
loading={fullLoading} | ||
loadingIndicator={<Spin tip="Loading..." />} | ||
/> | ||
<InfinityTable.PlaceHolder | ||
height={upperHeight} | ||
domNode={this.refUpperPlaceholder} | ||
loading={loading && !fullLoading} | ||
loadingIndicator={loadingIndicator} | ||
/> | ||
<InfinityTable.PlaceHolder | ||
height={underHeight} | ||
domNode={this.refUnderPlaceholder} | ||
loading={loading && !fullLoading} | ||
loadingIndicator={loadingIndicator} | ||
/> | ||
{total && pagination && ['top', 'both'].includes(pagination.position) && ( | ||
<Pagination | ||
showQuickJumper | ||
{...pagination} | ||
onChange={this.scrollToPage} | ||
current={currentPage} | ||
pageSize={pageSize} | ||
showSizeChanger={false} | ||
total={total} | ||
className={`infinity-page-table-pagination ${ | ||
pagination && pagination.className ? pagination.className : '' | ||
}`} | ||
/> | ||
)} | ||
<Table | ||
rowKey={record => record.key} | ||
{...rest} | ||
ref={forwardedRef} | ||
columns={columns} | ||
dataSource={dataSource} | ||
pagination={false} | ||
className={`infinity-page-table ${rest.className ? rest.className : ''}`} | ||
/> | ||
{total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && ( | ||
<Pagination | ||
showQuickJumper | ||
{...pagination} | ||
onChange={this.scrollToPage} | ||
current={currentPage} | ||
pageSize={pageSize} | ||
showSizeChanger={false} | ||
total={total} | ||
className={`infinity-page-table-pagination ${ | ||
pagination && pagination.className ? pagination.className : '' | ||
}`} | ||
/> | ||
)} | ||
</Fragment> | ||
) | ||
} | ||
} | ||
InfinityTable.defaultProps = { | ||
// loading 效果, A visual react component for Loading status | ||
loadingIndicator: ( | ||
<div | ||
style={{ | ||
textAlign: 'center', | ||
paddingTop: 20, | ||
paddingBottom: 20, | ||
border: '1px solid #e8e8e8', | ||
}} | ||
> | ||
<Spin tip="Loading..." /> | ||
</div> | ||
), | ||
pagination: { defaultCurrent: 1 }, // 分页器 | ||
onScroll: null, // 滚动事件 | ||
onFetch: noop, // 滚动到低部触发Fetch方法 | ||
bidirectionalCachePages: Infinity, // 当前页前后的缓存页码数量,默认为无限 | ||
total: 0, // 总共数据条数 | ||
debug: false, // display console log for debug | ||
loading: false, // 是否loading状态 | ||
pageSize: 30, // 每次Loading数据量,pageSize * 3 = 最大真实DOM大小,Reality DOM row count | ||
}; | ||
// loading 效果, A visual react component for Loading status | ||
loadingIndicator: ( | ||
<div | ||
style={{ | ||
textAlign: 'center', | ||
paddingTop: 20, | ||
paddingBottom: 20, | ||
border: '1px solid #e8e8e8', | ||
}} | ||
> | ||
<Spin tip="Loading..." /> | ||
</div> | ||
), | ||
pagination: { defaultCurrent: 1 }, // 分页器 | ||
onScroll: null, // 滚动事件 | ||
onFetch: noop, // 滚动到低部触发Fetch方法 | ||
bidirectionalCachePages: Infinity, // 当前页前后的缓存页码数量,默认为无限 | ||
total: 0, // 总共数据条数 | ||
debug: false, // display console log for debug | ||
loading: false, // 是否loading状态 | ||
pageSize: 30, // 每次Loading数据量,pageSize * 3 = 最大真实DOM大小,Reality DOM row count | ||
} | ||
InfinityTable.propTypes = { | ||
// loading 效果 | ||
className: string, | ||
loadingIndicator: element, | ||
onScroll: func, // 滚动事件 | ||
pagination: oneOfType([ | ||
bool, | ||
shape({ | ||
className: string, | ||
position: oneOf(['both', 'top', 'bottom']), | ||
className: string, | ||
defaultCurrent: number, | ||
hideOnSinglePage: bool, | ||
itemRender: func, | ||
showQuickJumper: bool, | ||
showTotal: func, | ||
simple: bool, | ||
size: string, | ||
onChange: func, | ||
}), | ||
]), | ||
onFetch: func.isRequired, // 滚动触发Fetch方法 | ||
pageSize: number.isRequired, | ||
bidirectionalCachePages: number.isRequired, | ||
total: number.isRequired, | ||
dataSource: array.isRequired, | ||
columns: array.isRequired, | ||
forwardedRef: object, | ||
debug: bool, | ||
loading: bool.isRequired, | ||
}; | ||
// loading 效果 | ||
className: string, | ||
loadingIndicator: element, | ||
onScroll: func, // 滚动事件 | ||
pagination: oneOfType([ | ||
bool, | ||
shape({ | ||
className: string, | ||
position: oneOf(['both', 'top', 'bottom']), | ||
className: string, | ||
defaultCurrent: number, | ||
hideOnSinglePage: bool, | ||
itemRender: func, | ||
showQuickJumper: bool, | ||
showTotal: func, | ||
simple: bool, | ||
size: string, | ||
onChange: func, | ||
}), | ||
]), | ||
onFetch: func.isRequired, // 滚动触发Fetch方法 | ||
pageSize: number.isRequired, | ||
bidirectionalCachePages: number.isRequired, | ||
total: number.isRequired, | ||
dataSource: array.isRequired, | ||
columns: array.isRequired, | ||
forwardedRef: object, | ||
debug: bool, | ||
loading: bool.isRequired, | ||
} | ||
export default React.forwardRef((props, ref) => ( | ||
<InfinityTable {...props} forwardedRef={ref} /> | ||
)); | ||
export default React.forwardRef((props, ref) => <InfinityTable {...props} forwardedRef={ref} />) | ||
export { InfinityTable } |
@@ -84,2 +84,2 @@ import { bool, number, array, object, func } from 'prop-types'; | ||
export default SumTable; | ||
export default SumTable; |
Sorry, the diff of this file is too big to display
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
303
0
1600090
33
4049