import React, { Component } from 'react'; import { Checkbox } from 'antd'; import memoizeOne from 'memoize-one'; import { ScrollSync, Grid, AutoSizer } from 'react-virtualized'; import 'react-virtualized/styles.css'; import _ from 'lodash'; import styles from './Table.less'; import { TableProps, TableState } from './interface'; import Column from './Column'; import Cell from './Cell'; export default class AirTable extends Component { static getDerivedStateFromProps(nextProps: TableProps, prevState: TableState) { const { prevProps } = prevState; let nextState: TableState = { ...prevState, prevProps: nextProps, }; if (JSON.stringify(prevProps.dataSource) !== JSON.stringify(nextProps.dataSource)) { nextState.dataSource = nextProps.dataSource; } if (JSON.stringify(prevProps.columns) !== JSON.stringify(nextProps.columns)) { nextState.columns = nextProps.columns; } return nextState; } constructor(props: TableProps) { super(props); const { columns, dataSource, tableId } = props; this.state = { columns, dataSource, tableId, prevProps: props, height: document.body.clientHeight - 193, }; this.indexCount = {}; this.config = { overscanColumnCount: 5, overscanRowCount: 5, columnWidth: 200, rowHeight: 40, }; this.memoizeLeftCount = memoizeOne(this.getLeftCount); this.memoizeData = memoizeOne(this.filterData); } //获取左侧固定列数量 getLeftCount = (columns: []) => { let len = 0; columns.map((item: any) => { item.fixed && len++; }); return len; }; //表头隐藏时过滤数据源 filterData = (columns: [], dataSource: []) => { if (columns.length === 0 || dataSource.length === 0) { return []; } let cloneData = _.cloneDeep(dataSource); let i = 0; this.indexCount = {}; cloneData.map((item1: any) => { item1.rowData = item1.rowData.filter((item2: any) => columns.some((temp: any) => temp.columnName === item2.colName), ); if (item1.groupId) { if (this.indexCount[item1.groupId]) { this.indexCount[item1.groupId].push(item1.id); } else { i++; this.indexCount[item1.groupId] = [item1.id]; } item1.index = i; } return item1; }); return cloneData; }; //下拉加载 onScrollRow = ({ clientHeight, scrollTop }: any) => { const height = clientHeight + scrollTop || 0; const { dataSource = [], rowHeight = 40 } = this.state; const offset = 100; if (dataSource.length === 0) return; if (height + offset >= dataSource.length * rowHeight) { this.props.onScroll && this.props.onScroll(); } else return; }; //渲染表头 renderHeaderCell = ({ columnIndex, key, rowIndex, style }: any) => { const { columns } = this.state; if (columns.length === 0) return null; const { columnType, columnChsName, width } = columns[columnIndex] || {}; if (columnIndex === 0) { return (
); } return (
); }; //渲染数据 renderBodyCell = (data: [], { columnIndex, key, rowIndex, style }: any) => { const { columns } = this.state; if (columns.length === 0 || data.length === 0) { return; } const rowData: any = data[rowIndex] || {}; const columnData: any = (rowData.rowData && rowData.rowData[columnIndex]) || {}; const cellData: [] = columnData.cellValueList || []; let columnConfig = columns[columnIndex]; let className = styles.indexCell; if (columnIndex === 0) { return (
); } return (
); }; render() { const { columns, dataSource, checked } = this.state; const { overscanColumnCount, overscanRowCount, columnWidth, rowHeight } = this.config; let { height } = this.state; if (dataSource.length * rowHeight < height) { height = dataSource.length * rowHeight; } //有隐藏列时,修正数据与列头不匹配问题 const data = this.memoizeData(columns, dataSource); //左侧固定列数量 const leftCount = this.memoizeLeftCount(columns); const rowCount = dataSource.length; const columnCount = columns.length; return ( <> {({ onScroll, scrollLeft, scrollTop }: any) => { return (
{ //左侧表头
} { //左侧固定列
}
{({ width }: any) => (
{ //右侧表头
} { //右侧内容
) => { onScroll(...arg); this.onScrollRow(...arg); }} cellRenderer={this.renderBodyCell.bind(this, data)} columns={columns} checked={checked} />
}
)}
); }}
); } }