增加树状表

This commit is contained in:
wanghaoo 2019-01-03 16:21:24 +08:00
parent 6b377718a5
commit d55e29ee43
12 changed files with 1026 additions and 237 deletions

View File

@ -204,11 +204,11 @@ class Demo25 extends Component {
columns={columns} columns={columns}
data={dataList} data={dataList}
getSelectedDataFunc={this.getSelectedDataFunc} getSelectedDataFunc={this.getSelectedDataFunc}
bordered
checkMinSize={7} checkMinSize={7}
draggable={true} draggable={true}
multiSelect={{type: "checkbox"}} multiSelect={{type: "checkbox"}}
scroll={{x:"130%", y: 100}} scroll={{x:true, y: 100}}
selectedRow={this.selectedRow} selectedRow={this.selectedRow}
// scroll={{x:this.getCloumnsScroll(columns), y: 150}} // scroll={{x:this.getCloumnsScroll(columns), y: 150}}
/> />

115
demo/demolist/Demo34.js Normal file
View File

@ -0,0 +1,115 @@
/**
*
* @title 树状结构的大数据场景
* Tooltip
* @description
*/
import React, { Component } from "react";
import Tooltip from "bee-tooltip";
import Table from "../../src";
import BigData from "../../src/lib/bigData";
const BigDataTable = BigData(Table);
const columns = [
{
title:'序号',
dataIndex:'index',
width:'150',
render:(text,record,index)=>{
return index
}
},
{
title: "用户名", dataIndex: "a", key: "a", width: 580, className: "rowClassName",
render: (text, record, index) => {
return (
<Tooltip inverse overlay={text}>
<span tootip={text} style={{
display: "inline-block",
width: "80px",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
verticalAlign: "middle",
}}>{text}</span>
</Tooltip>
);
}
},
{ id: "123", title: "性别", dataIndex: "b", key: "b", width: 80},
{ title: "年龄", dataIndex: "c", key: "c", width: 200 },
{
title: "操作",
dataIndex: "d",
key: "d",
fixed:'right',
render(text, record, index) {
return (
<div style={{ position: 'relative' }} title={text} >
<a
href="javascript:;"
tooltip={text}
onClick={() => {
alert('这是第' + index + '列,内容为:' + text);
}}
>
一些操作
</a>
</div>
);
}
}
];
const data = [ ...new Array(1000) ].map((e, i) => {
const rs = { a: i + 'a', b: i + 'b', c: i + 'c', d: i + 'd', key: i };
if(i%3==0){
rs.b = '女';
rs.children = [];
for(let subi=0;subi<3;subi++){
rs.children.push({a: i +subi + 'asub', b: i +subi + 'bsub', c: i + subi +'csub', d: i + subi +'dsub', key: i+ `${subi} sub`});
}
}else{
rs.children = [];
for(let subi=0;subi<3;subi++){
rs.children.push({a: i +subi + 'asub', b: i +subi + 'bsub', c: i + subi +'csub', d: i + subi +'dsub', key: i+ `${subi} sub`});
}
}
return rs;
})
class Demo30 extends Component {
constructor(props) {
super(props);
this.state = {
data: data,
selectedRowIndex: 0
}
}
onExpandedRowsChange = (params)=>{
console.log(params);
}
onExpand = (expandKeys)=>{
console.log('expand---'+expandKeys);
}
render() {
return (
<BigDataTable
columns={columns}
data={data}
parentNodeId='parent'
scroll={{y:300}}
height={40}
onRowClick={(record, index, indent) => {
console.log('currentIndex--'+index);
}}
/>
);
}
}
export default Demo30;

File diff suppressed because one or more lines are too long

3
dist/demo.css vendored
View File

@ -8637,8 +8637,7 @@ ul {
zoom: 1; zoom: 1;
line-height: 4px; line-height: 4px;
height: 4px; height: 4px;
color: #999; color: #999; }
transition: all 0.3s; }
.u-table-thead th:hover .bee-table-column-sorter { .u-table-thead th:hover .bee-table-column-sorter {
display: inline-block; } display: inline-block; }
.u-table-thead .th-drag { .u-table-thead .th-drag {

2
dist/demo.css.map vendored

File diff suppressed because one or more lines are too long

611
dist/demo.js vendored

File diff suppressed because one or more lines are too long

2
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -79,7 +79,9 @@ const defaultProps = {
columns:[], columns:[],
minColumnWidth: 80, minColumnWidth: 80,
locale:{}, locale:{},
syncHover: true syncHover: true,
setRowHeight:()=>{},
setRowParentIndex:()=>{}
}; };
class Table extends Component { class Table extends Component {
@ -192,6 +194,7 @@ class Table extends Component {
} }
if (!nextProps.originWidth) { if (!nextProps.originWidth) {
this.computeTableWidth(); this.computeTableWidth();
this.firstDid = true;//避免重复update
} }
} }
@ -202,8 +205,9 @@ class Table extends Component {
this.syncFixedTableRowHeight(); this.syncFixedTableRowHeight();
} }
//适应模态框中表格、以及父容器宽度变化的情况 //适应模态框中表格、以及父容器宽度变化的情况
if (typeof (this.props.scroll.x) !== 'number' && this.contentTable.getBoundingClientRect().width !== this.contentDomWidth) { if (typeof (this.props.scroll.x) !== 'number' && this.contentTable.getBoundingClientRect().width !== this.contentDomWidth && this.firstDid) {
this.computeTableWidth(); this.computeTableWidth();
this.firstDid = false;//避免重复update
} }
if(this.scrollTop){ if(this.scrollTop){
this.refs.fixedColumnsBodyLeft && ( this.refs.fixedColumnsBodyLeft.scrollTop = this.scrollTop); this.refs.fixedColumnsBodyLeft && ( this.refs.fixedColumnsBodyLeft.scrollTop = this.scrollTop);
@ -483,8 +487,19 @@ class Table extends Component {
/> />
); );
} }
/**
getRowsByData(data, visible, indent, columns, fixed) { *
*
* @param {*} data
* @param {*} visible
* @param {*} indent 层级
* @param {*} columns
* @param {*} fixed
* @param {number} [rootIndex=-1] 祖级节点
* @returns
* @memberof Table
*/
getRowsByData(data, visible, indent, columns, fixed,rootIndex=-1) {
const props = this.props; const props = this.props;
const childrenColumnName = props.childrenColumnName; const childrenColumnName = props.childrenColumnName;
const expandedRowRender = props.expandedRowRender; const expandedRowRender = props.expandedRowRender;
@ -502,13 +517,13 @@ class Table extends Component {
const expandIconAsCell = fixed !== 'right' ? props.expandIconAsCell : false; const expandIconAsCell = fixed !== 'right' ? props.expandIconAsCell : false;
const expandIconColumnIndex = fixed !== 'right' ? props.expandIconColumnIndex : -1; const expandIconColumnIndex = fixed !== 'right' ? props.expandIconColumnIndex : -1;
if(props.lazyLoad && props.lazyLoad.preHeight){ if(props.lazyLoad && props.lazyLoad.preHeight && indent == 0){
rst.push( rst.push(
<TableRow height={props.lazyLoad.preHeight} columns={[]} className='' store={this.store} visible = {true}/> <TableRow height={props.lazyLoad.preHeight} columns={[]} className='' store={this.store} visible = {true}/>
) )
} }
const lazyCurrentIndex = props.lazyLoad && props.lazyLoad.startIndex ?props.lazyLoad.startIndex :0; const lazyCurrentIndex = props.lazyLoad && props.lazyLoad.startIndex ?props.lazyLoad.startIndex :0;
const lazyParentIndex = props.lazyLoad && props.lazyLoad.startParentIndex ?props.lazyLoad.startParentIndex :0;
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const record = data[i]; const record = data[i];
const key = this.getRowKey(record, i); const key = this.getRowKey(record, i);
@ -518,7 +533,7 @@ class Table extends Component {
let expandedContentHeight = 0; let expandedContentHeight = 0;
if (expandedRowRender && isRowExpanded) { if (expandedRowRender && isRowExpanded) {
expandedRowContent = expandedRowRender(record, i, indent); expandedRowContent = expandedRowRender(record, i, indent);
expandedContentHeight = parseInt(expandedRowContent.props.style && expandedRowContent.props.style.height?expandedRowContent.props.style.height:0); expandedContentHeight = parseInt(expandedRowContent.props && expandedRowContent.props.style && expandedRowContent.props.style.height?expandedRowContent.props.style.height:0);
} }
//只有当使用expandedRowRender参数的时候才去识别isHiddenExpandIcon隐藏行展开的icon //只有当使用expandedRowRender参数的时候才去识别isHiddenExpandIcon隐藏行展开的icon
if (expandedRowRender && typeof props.haveExpandIcon == 'function') { if (expandedRowRender && typeof props.haveExpandIcon == 'function') {
@ -530,6 +545,7 @@ class Table extends Component {
if (this.columnManager.isAnyColumnsFixed()) { if (this.columnManager.isAnyColumnsFixed()) {
onHoverProps.onHover = this.handleRowHover; onHoverProps.onHover = this.handleRowHover;
} }
//fixedIndex一般是跟index是一个值的只有是树结构时会讲子节点的值也累计上
let fixedIndex = i; let fixedIndex = i;
//判断是否是tree结构 //判断是否是tree结构
if (this.treeType) { if (this.treeType) {
@ -556,8 +572,14 @@ class Table extends Component {
if(i == data.length -1 && props.showSum){ if(i == data.length -1 && props.showSum){
className = className + ' sumrow'; className = className + ' sumrow';
} }
let paramRootIndex = rootIndex;
//小于0说明为第一层节点她的子孙节点要保存自己的根节点
if(paramRootIndex<0){
paramRootIndex = i+lazyParentIndex;
}
// console.log('rootIndex',rootIndex,'index',fixedIndex,'fixedIndex',fixedIndex,'paramRootIndex',paramRootIndex,'key',record.key);
rst.push( rst.push(
<TableRow <TableRow
indent={indent} indent={indent}
@ -567,7 +589,7 @@ class Table extends Component {
record={record} record={record}
expandIconAsCell={expandIconAsCell} expandIconAsCell={expandIconAsCell}
onDestroy={this.onRowDestroy} onDestroy={this.onRowDestroy}
index={fixedIndex+lazyCurrentIndex} index={i+lazyParentIndex}
visible={visible} visible={visible}
expandRowByClick={expandRowByClick} expandRowByClick={expandRowByClick}
onExpand={this.onExpanded} onExpand={this.onExpanded}
@ -590,6 +612,11 @@ class Table extends Component {
lazyCurrentIndex={lazyCurrentIndex} lazyCurrentIndex={lazyCurrentIndex}
expandedContentHeight={expandedContentHeight} expandedContentHeight={expandedContentHeight}
setRowHeight={props.setRowHeight} setRowHeight={props.setRowHeight}
setRowParentIndex={props.setRowParentIndex}
treeType={childrenColumn||this.treeType?true:false}
fixedIndex={fixedIndex+lazyCurrentIndex}
rootIndex = {rootIndex}
/> />
); );
this.treeRowIndex++; this.treeRowIndex++;
@ -603,12 +630,12 @@ class Table extends Component {
if (childrenColumn) { if (childrenColumn) {
this.treeType = true;//证明是tree表形式visible = {true} this.treeType = true;//证明是tree表形式visible = {true}
rst = rst.concat(this.getRowsByData( rst = rst.concat(this.getRowsByData(
childrenColumn, subVisible, indent + 1, columns, fixed childrenColumn, subVisible, indent + 1, columns, fixed,paramRootIndex
)); ));
} }
} }
if(props.lazyLoad && props.lazyLoad.sufHeight){ if(props.lazyLoad && props.lazyLoad.sufHeight && indent == 0){
rst.push( rst.push(
<TableRow height={props.lazyLoad.sufHeight} columns={[]} className='' store={this.store} visible = {true}/> <TableRow height={props.lazyLoad.sufHeight} columns={[]} className='' store={this.store} visible = {true}/>
) )
@ -996,9 +1023,8 @@ class Table extends Component {
this.lastScrollTop = e.target.scrollTop; this.lastScrollTop = e.target.scrollTop;
if(handleScroll){ if(handleScroll){
debounce( debounce(
handleScroll(this.lastScrollTop) handleScroll(this.lastScrollTop,this.treeType),
,500); 300)
} }
} }

View File

@ -360,8 +360,8 @@ $checkbox-height:16px;
line-height: 4px; line-height: 4px;
height: 4px; height: 4px;
color: #999; color: #999;
-webkit-transition: all 0.3s; // -webkit-transition: all 0.3s;
transition: all 0.3s; // transition: all 0.3s;
} }
&:hover{ &:hover{
.bee-table-column-sorter { .bee-table-column-sorter {

View File

@ -38,7 +38,8 @@ const defaultProps = {
expandIconColumnIndex: 0, expandIconColumnIndex: 0,
expandRowByClick: false, expandRowByClick: false,
onHover() {}, onHover() {},
className:'' className:'',
setRowParentIndex:()=>{}
}; };
class TableRow extends Component{ class TableRow extends Component{
@ -57,7 +58,7 @@ class TableRow extends Component{
componentDidMount() { componentDidMount() {
const { store, hoverKey } = this.props; const { store, hoverKey,treeType } = this.props;
this.unsubscribe = store.subscribe(() => { this.unsubscribe = store.subscribe(() => {
if (store.getState().currentHoverKey === hoverKey) { if (store.getState().currentHoverKey === hoverKey) {
this.setState({ hovered: true }); this.setState({ hovered: true });
@ -67,13 +68,24 @@ class TableRow extends Component{
}); });
this.setRowHeight() this.setRowHeight()
if(treeType){
this.setRowParentIndex();
}
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (this.props.index !== prevProps.index) { if(this.props.treeType){
this.setRowParentIndex();
if(this.props.fixedIndex!== prevProps.fixedIndex){
this.setRowHeight()
}
}else if(this.props.index !== prevProps.index){
this.setRowHeight() this.setRowHeight()
} }
} }
componentWillUnmount() { componentWillUnmount() {
const { record, onDestroy, index } = this.props; const { record, onDestroy, index } = this.props;
@ -85,11 +97,17 @@ class TableRow extends Component{
setRowHeight() { setRowHeight() {
const { setRowHeight , expandedContentHeight=0,lazyCurrentIndex=0,fixed} = this.props const { setRowHeight , expandedContentHeight=0,lazyCurrentIndex=0,fixed,fixedIndex} = this.props
if (!setRowHeight || !this.element || fixed) return if (!setRowHeight || !this.element || fixed) return
setRowHeight(this.element.clientHeight + expandedContentHeight, this.props.index) setRowHeight(this.element.clientHeight + expandedContentHeight, fixedIndex)
} }
setRowParentIndex(){
const {index,setRowParentIndex,fixedIndex,rootIndex} = this.props;
// console.log('rootIndex',rootIndex<0?index:rootIndex,'index',fixedIndex);
setRowParentIndex(rootIndex<0?index:rootIndex,fixedIndex);
}
onRowClick(event) { onRowClick(event) {
const { const {
record, record,

View File

@ -1,37 +1,118 @@
import React, { Component } from "react"; import React, { Component } from "react";
import PropTypes from 'prop-types'; import PropTypes from "prop-types";
import { warningOnce } from '../utils';
const defaultHeight = 40; const defaultHeight = 40;
const rowDiff = 3;//行差值 const rowDiff = 3; //行差值
let treeTypeIndex = 0;
export default function bigData(Table) { export default function bigData(Table) {
return class BigData extends Component { return class BigData extends Component {
static defaultProps = {
static defaultProps = { data: [],
data: [], loadBuffer: 5,
loadBuffer:5 rowKey: 'key',
}; };
static propTypes = { static propTypes = {
loadBuffer: PropTypes.number, loadBuffer: PropTypes.number
} };
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
scrollLeft: 0, scrollLeft: 0,
scrollTop: 0 scrollTop: 0
}; };
const rowHeight = this.props.height?this.props.height:defaultHeight const rowHeight = this.props.height ? this.props.height : defaultHeight;
//默认显示25条rowsInView根据定高算的。在非固定高下这个只是一个大概的值。 //默认显示25条rowsInView根据定高算的。在非固定高下这个只是一个大概的值。
const scrollY = this.props.scroll.y ? parseInt(this.props.scroll.y) : 0; const scrollY = this.props.scroll.y ? parseInt(this.props.scroll.y) : 0;
this.rowsInView = scrollY ?Math.ceil(scrollY/rowHeight):20 ; this.rowsInView = scrollY ? Math.ceil(scrollY / rowHeight) : 20;
this.currentIndex = 0; this.currentIndex = 0;
this.loadCount = props.loadBuffer? this.rowsInView + props.loadBuffer*2:26;//一次加载多少数据 this.loadCount = props.loadBuffer
this.cachedRowHeight = [];//缓存每行的高度 ? this.rowsInView + props.loadBuffer * 2
: 26; //一次加载多少数据
this.cachedRowHeight = []; //缓存每行的高度
this.cachedRowParentIndex=[];
this.expandChildRowKeys=[];
this.firstLevelKey=[];
this.keys=[];
this.lastScrollTop = 0; this.lastScrollTop = 0;
this.currentScrollTop = 0; this.currentScrollTop = 0;
this.startIndex = this.currentIndex;//数据开始位置 this.startIndex = this.currentIndex; //数据开始位置
this.endIndex = this.currentIndex + this.loadCount//数据结束位置 this.endIndex = this.currentIndex + this.loadCount; //数据结束位置
this.setRowHeight = this.setRowHeight.bind(this); this.setRowHeight = this.setRowHeight.bind(this);
this.setRowParentIndex = this.setRowParentIndex.bind(this);
}
componentWillReceiveProps(nextProps){
if(nextProps.scroll.y !== this.props.scroll.y){
const scrollY = nextProps.scroll.y ? parseInt(nextProps.scroll.y) : 0;
this.rowsInView = scrollY ? Math.ceil(scrollY / rowHeight) : 20;
this.loadCount = props.loadBuffer
? this.rowsInView + props.loadBuffer * 2
: 26; //一次加载多少数据
this.currentIndex = 0;
this.startIndex = this.currentIndex; //数据开始位置
this.endIndex = this.currentIndex + this.loadCount; //数据结束位置
}
}
componentDidMount(){
const isTreeType = this.checkIsTreeType();
if(isTreeType){
const {data} = this.props;
data.forEach((item,index)=>{
this.firstLevelKey[index] = this.getRowKey(item,index);
this.cachedRowParentIndex[treeTypeIndex] = index;
//保存所有的keys跟小标对应起来
this.keys[treeTypeIndex] = this.getRowKey(item,index);
treeTypeIndex++;
if(item.children){
this.getData(item.children,index);
}
});
}
// console.log("***data********++++++++++++",this.cachedRowParentIndex);
}
getRowKey(record, index) {
const rowKey = this.props.rowKey;
const key = (typeof rowKey === 'function') ?
rowKey(record, index) : record[rowKey];
warningOnce(
key !== undefined,
'Each record in table should have a unique `key` prop,' +
'or set `rowKey` to an unique primary key.'
);
return key;
}
/**
*判断是否是树形结构
*
*/
checkIsTreeType(){
const {data} = this.props;
let rs = false;
//取前三十个看看是否有children属性有则为树形结构
for(let i = 0 ;i<30;i++){
if(data[i].children){
rs = true;
break;
}
}
return rs;
}
getData(data,parentIndex){
data.forEach((subItem,subIndex)=>{
this.cachedRowParentIndex[treeTypeIndex] = parentIndex;
this.keys[treeTypeIndex] = this.getRowKey(subItem,subIndex);
treeTypeIndex++;
if(subItem.children){
this.getData(subItem.children,parentIndex);
}
})
}
componentWillUnmount(){
this.cachedRowHeight = [];
this.cachedRowParentIndex = [];
} }
/** /**
*获取数据区高度 *获取数据区高度
@ -45,114 +126,244 @@ export default function bigData(Table) {
getSumHeight(start, end) { getSumHeight(start, end) {
const { height } = this.props; const { height } = this.props;
const rowHeight = height?height:defaultHeight; const rowHeight = height ? height : defaultHeight;
let sumHeight = 0; let sumHeight = 0;
for (let i = start; i < end; i++) { for (let i = start; i < end; i++) {
sumHeight += this.cachedRowHeight[i] || rowHeight; sumHeight += this.cachedRowHeight[i] || rowHeight;
} }
return sumHeight; return sumHeight;
} }
/**
*@description 根据返回的scrollTop计算当前的索引此处做了两次缓存一个是根据上一次的currentIndex计算当前currentIndex另一个是根据当前内容区的数据是否在缓存中如果在则不重新render页面 /**
*@param 最新一次滚动的scrollTop *@description 根据返回的scrollTop计算当前的索引此处做了两次缓存一个是根据上一次的currentIndex计算当前currentIndex另一个是根据当前内容区的数据是否在缓存中如果在则不重新render页面
*/ *@param 最新一次滚动的scrollTop
handleScroll = (nextScrollTop)=> { *@param treeType是否是树状表
const _this = this; */
const {data,height,scroll={},loadBuffer} = _this.props; handleScroll = (nextScrollTop, treeType) => {
const rowHeight = height?height:defaultHeight; //树表逻辑
const {currentIndex = 0 ,loadCount,scrollTop,currentScrollTop} = _this; // 关键点是动态的获取startIndex和endIndex
let {endIndex,startIndex} = _this; // 法子一子节点也看成普通tr最开始需要设置一共有多少行哪行显示哪行不显示如何确定
const {needRender} = _this.state; // 动态取start = current+buffer对应的父节点、end = start+loadCount+row的height为0的行数 展开节点的下一个节点作为end值
const viewHeight = parseInt(scroll.y); const _this = this;
// let index = currentIndex;//记录下次当前位置 const { data, height, scroll = {}, loadBuffer } = _this.props;
// let temp = currentIndex ?nextScrollTop - currentScrollTop:nextScrollTop; const rowHeight = height ? height : defaultHeight;
const {
// const isOrder = temp > 0 ?true:false;//true为向下滚动、false为向上滚动 currentIndex = 0,
loadCount,
// //根据scrollTop计算下次当前索引的位置 scrollTop,
// if(isOrder){ currentScrollTop
// while (temp > 0) { } = _this;
// temp -= this.cachedRowHeight[index] || rowHeight let { endIndex, startIndex } = _this;
// if(temp > 0){ const { needRender } = _this.state;
// index += 1 const viewHeight = parseInt(scroll.y);
// //保存当前index对应的scrollTop _this.treeType = treeType;
// this.currentScrollTop += this.cachedRowHeight[index]|| rowHeight; // let index = currentIndex;//记录下次当前位置
// } // let temp = currentIndex ?nextScrollTop - currentScrollTop:nextScrollTop;
// }
// }else{ // const isOrder = temp > 0 ?true:false;//true为向下滚动、false为向上滚动
// while(temp < 0){
// temp += this.cachedRowHeight[index] || rowHeight // //根据scrollTop计算下次当前索引的位置
// if(temp < 0){ // if(isOrder){
// index -= 1 // while (temp > 0) {
// this.currentScrollTop -= this.cachedRowHeight[index]|| rowHeight; // temp -= this.cachedRowHeight[index] || rowHeight
// } // if(temp > 0){
// } // index += 1
// } // //保存当前index对应的scrollTop
let index = 0; // this.currentScrollTop += this.cachedRowHeight[index]|| rowHeight;
let temp = nextScrollTop; // }
while (temp > 0) { // }
temp -= this.cachedRowHeight[index] || rowHeight // }else{
if(temp > 0){ // while(temp < 0){
index += 1 // temp += this.cachedRowHeight[index] || rowHeight
// if(temp < 0){
// index -= 1
// this.currentScrollTop -= this.cachedRowHeight[index]|| rowHeight;
// }
// }
// }
let index = 0;
let temp = nextScrollTop;
let currentKey;
while (temp >0) {
// console.log('获取index-----',this.cachedRowHeight[index]);
let currentRowHeight = this.cachedRowHeight[index];
if(currentRowHeight === undefined){
if(this.treeType){
currentKey = this.keys[index];
currentRowHeight = 0;
if(this.firstLevelKey.indexOf(currentKey)>=0 || this.expandChildRowKeys.indexOf(currentKey)>=0){
currentRowHeight = rowHeight;
}
}else{
currentRowHeight = rowHeight;
}
}
temp -= currentRowHeight;
if (temp > 0) {
index += 1;
}
}
// console.log('while循环获取index次数-----',index);
const isOrder = index - currentIndex > 0 ? true : false;
if (index < 0) index = 0;
console.log("currentIndex****" + index);
//如果之前的索引和下一次的不一样则重置索引和滚动的位置
if (currentIndex !== index) {
_this.currentIndex = index;
_this.scrollTop = nextScrollTop;
let rowsInView = 0; //可视区域显示多少行
let rowsHeight = 0; //可视区域内容高度
let tempIndex = index;
//如果可视区域中需要展示的数据已经在缓存中则不重现render。
if (viewHeight) {
//有时滚动过快时this.cachedRowHeight[rowsInView + index]为undifined
while (rowsHeight < viewHeight && tempIndex<this.cachedRowHeight.length) {
// console.log("rowsHeight < viewHeight",tempIndex,rowsHeight,viewHeight,this.cachedRowHeight);
if(this.cachedRowHeight[tempIndex]){
rowsHeight += this.cachedRowHeight[tempIndex];
if(treeType && _this.cachedRowParentIndex[tempIndex] !== tempIndex ||!treeType){
rowsInView++;
}
}
tempIndex++;
}
// console.log("rowsHeight < viewHeight循环次数",tempIndex-index);
if(treeType){
const treeIndex = index
index = _this.cachedRowParentIndex[treeIndex];
if(index === undefined){
console.log('index is undefined********'+treeIndex);
index = this.getParentIndex(treeIndex);
console.log("getParentIndex****"+index);
}
}
console.log('parentIndex*********',index);
// 如果rowsInView 小于 缓存的数据则重新render
// 向下滚动 下临界值超出缓存的endIndex则重新渲染
if (rowsInView + index > endIndex - rowDiff && isOrder) {
startIndex = index - loadBuffer>0?index - loadBuffer:0;
endIndex = startIndex + loadCount;
//树状结构则根据当前的节点重新计算startIndex和endIndex
// if(treeType){
// const currentParentIndex = _this.cachedRowParentIndex[index];
// startIndex = currentParentIndex - loadBuffer>0?currentParentIndex - loadBuffer:0;
// endIndex = startIndex + loadCount;
// // console.log(endIndex,"endIndex的parentIndex",parentEndIndex);
// // endIndex = parentEndIndex +1
// }else{
// startIndex = index - loadBuffer>0?index - loadBuffer:0;
// endIndex = startIndex + loadCount;
// }
if (endIndex > data.length) {
endIndex = data.length;
}
if(startIndex!==this.startIndex||endIndex!==this.endIndex){
this.startIndex = startIndex;
this.endIndex = endIndex;
this.setState({ needRender: !needRender });
}
console.log(
"===================",
"**index**" + index,
" **startIndex**" + this.startIndex,
"**endIndex**" + this.endIndex
);
}
// 向上滚动当前的index是否已经加载currentIndex若干上临界值小于startIndex则重新渲染
if (!isOrder && index < startIndex + rowDiff) {
startIndex = index - loadBuffer;
if (startIndex < 0) {
startIndex = 0;
}
if(startIndex!==this.startIndex||endIndex!==this.endIndex){
this.startIndex = startIndex;
this.endIndex = this.startIndex + loadCount;
this.setState({ needRender: !needRender });
}
console.log(
"**index**" + index,
"**startIndex**" + this.startIndex,
"**endIndex**" + this.endIndex
);
} }
} }
const isOrder = index - currentIndex > 0 ?true:false;
if (index < 0) index = 0 }
console.log('currentIndex****'+index); };
//如果之前的索引和下一次的不一样则重置索引和滚动的位置
if(currentIndex !== index){
_this.currentIndex = index;
_this.scrollTop = nextScrollTop;
let rowsInView = 0 ; //可视区域显示多少行
let rowsHeight = 0; //可视区域内容高度
//如果可视区域中需要展示的数据已经在缓存中则不重现render。
if(viewHeight){
//有时滚动过快时this.cachedRowHeight[rowsInView + index]为undifined
while(rowsHeight < viewHeight && this.cachedRowHeight[rowsInView + index] ){
rowsHeight += this.cachedRowHeight[rowsInView + index];
rowsInView++;
}
// 如果rowsInView 小于 缓存的数据则重新render
// 向下滚动 下临界值超出缓存的endIndex则重新渲染
if(rowsInView+index > endIndex - rowDiff && isOrder){
this.startIndex = index - loadBuffer;
endIndex = this.startIndex + loadCount
if(endIndex > data.length){
endIndex = data.length
}
this.endIndex = endIndex;
this.setState({needRender: !needRender });
}
// 向上滚动当前的index是否已经加载currentIndex若干上临界值小于startIndex则重新渲染
if(!isOrder && index < startIndex + rowDiff){
startIndex = index - loadBuffer;
if(startIndex<0){
startIndex = 0;
}
this.startIndex = startIndex;
this.endIndex = this.startIndex + loadCount
this.setState({needRender: !needRender });
}
}
console.log('**index**'+index,"**startIndex**"+this.startIndex,"**endIndex**"+this.endIndex);
}
}
setRowHeight(height, index) { setRowHeight(height, index) {
this.cachedRowHeight[index] = height this.cachedRowHeight[index] = height;
}
setRowParentIndex(parentIndex,index){
// this.cachedRowParentIndex[index] = parentIndex;
}
/**
*
*根据当前行号获取该行的父节点行号
* @param {*} currentIndex 当前行号
*/
getParentIndex(targetIndex) {
const {data} = this.props;
let parentIndex = -1;
parentIndex = this.getIndex(data,-1,targetIndex);
if(parentIndex<0){//小于0说明没有展开的子节点
parentIndex = targetIndex;
}
return parentIndex;
}
getIndex(data,index,targetIndex){
const parentIndex = index;
for(let i=0;i<data.length;i++){
index++;
if(targetIndex <=index){
break;
}
if(data[i].children){
this.getIndex(data[i].children,index,targetIndex);
}
}
return parentIndex;
}
onExpand = (expandState,record)=>{
const _this = this;
// 展开
if(expandState){
record.children && record.children.forEach((item,index)=>{
_this.expandChildRowKeys.push( _this.getRowKey(item,index));
})
}else{
// 收起
record.children && record.children.forEach((item,index)=>{
_this.expandChildRowKeys.splice(_this.expandChildRowKeys.findIndex(fitem => fitem.key === item.key), 1)
})
}
} }
render() { render() {
const { data } = this.props; const { data } = this.props;
const { scrollTop } = this; const { scrollTop } = this;
const {endIndex,startIndex} = this; const { endIndex, startIndex } = this;
const lazyLoad = { const lazyLoad = {
preHeight: this.getSumHeight(0, startIndex), preHeight: this.getSumHeight(0, startIndex),
sufHeight: this.getSumHeight(endIndex , data.length), sufHeight: this.getSumHeight(endIndex, data.length),
startIndex:startIndex startIndex: startIndex,
startParentIndex:startIndex,//为树状节点做准备
}; };
if(this.treeType){
const preSubCounts = this.cachedRowParentIndex.findIndex(item=>{ return item==startIndex })
if(preSubCounts>0){
lazyLoad.startIndex = preSubCounts;
}
}
return ( return (
<Table <Table
{...this.props} {...this.props}
@ -161,10 +372,12 @@ handleScroll = (nextScrollTop)=> {
handleScroll={this.handleScroll} handleScroll={this.handleScroll}
scrollTop={scrollTop} scrollTop={scrollTop}
setRowHeight={this.setRowHeight} setRowHeight={this.setRowHeight}
// className={'lazy-table'} setRowParentIndex = {this.setRowParentIndex}
onExpand = {this.onExpand}
onExpandedRowsChange = {this.onExpandedRowsChange}
// className={'lazy-table'}
/> />
); );
} }
}; };
} }

View File

@ -66,4 +66,7 @@ export function ObjectAssign(obj){
Object.assign(tagObj,obj); Object.assign(tagObj,obj);
} }
return tagObj; return tagObj;
} }