树形表多级懒加载
This commit is contained in:
parent
d3b4cb34de
commit
cc2a624fe6
|
@ -867,7 +867,8 @@ var Table = function (_Component) {
|
|||
// }
|
||||
var record = data[i];
|
||||
var key = this.getRowKey(record, i);
|
||||
var childrenColumn = record[childrenColumnName];
|
||||
var isLeaf = typeof record['isLeaf'] === 'boolean' && record['isLeaf'] || false;
|
||||
var childrenColumn = isLeaf ? false : record[childrenColumnName];
|
||||
var isRowExpanded = this.isRowExpanded(record, i);
|
||||
var expandedRowContent = void 0;
|
||||
var expandedContentHeight = 0;
|
||||
|
|
|
@ -16,10 +16,14 @@ var _propTypes = require("prop-types");
|
|||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
var _utils = require("./utils");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
|
||||
|
||||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||
|
@ -64,6 +68,9 @@ function bigData(Table) {
|
|||
_this2.setRowHeight = _this2.setRowHeight.bind(_this2);
|
||||
_this2.setRowParentIndex = _this2.setRowParentIndex.bind(_this2);
|
||||
_this2.expandedRowKeys = [];
|
||||
_this2.flatTreeKeysMap = {}; //树表,扁平结构数据的 Map 映射,方便获取各节点信息
|
||||
_this2.flatTreeData = []; //深度遍历处理后的data数组
|
||||
_this2.treeData = []; //树表的data数据
|
||||
return _this2;
|
||||
}
|
||||
|
||||
|
@ -98,12 +105,41 @@ function bigData(Table) {
|
|||
}
|
||||
};
|
||||
|
||||
BigData.prototype.componentDidMount = function componentDidMount() {
|
||||
var data = this.props.data;
|
||||
BigData.prototype.componentWillMount = function componentWillMount() {
|
||||
var endIndex = this.endIndex,
|
||||
startIndex = this.startIndex;
|
||||
|
||||
var sliceTreeList = [];
|
||||
var _props = this.props,
|
||||
data = _props.data,
|
||||
isTree = _props.isTree;
|
||||
|
||||
var isTreeType = isTree ? true : this.checkIsTreeType();
|
||||
//设置data中每个元素的parentIndex
|
||||
this.computeCachedRowParentIndex(data);
|
||||
//如果是树表,递归data
|
||||
if (isTreeType) {
|
||||
this.treeType = isTreeType;
|
||||
var flatTreeData = this.deepTraversal(data);
|
||||
sliceTreeList = flatTreeData.slice(startIndex, endIndex);
|
||||
this.flatTreeData = flatTreeData;
|
||||
this.handleTreeListChange(sliceTreeList);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 深度遍历树形 data,把数据拍平,变为一维数组
|
||||
* @param {*} data
|
||||
* @param {*} parentKey 标识父节点
|
||||
* @param {*} isShown 该节点是否显示在页面中,当节点的父节点是展开状态 或 该节点是根节点时,该值为 true
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 将截取后的 List 数组转换为 Tree 结构,并更新 state
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*设置data中每个元素的parentIndex
|
||||
*
|
||||
|
@ -206,9 +242,10 @@ function bigData(Table) {
|
|||
for (var i = start; i < end; i++) {
|
||||
if (this.cachedRowHeight[i] == undefined) {
|
||||
if (this.treeType) {
|
||||
currentKey = this.keys[i];
|
||||
// currentKey = this.keys[i];
|
||||
currentKey = this.flatTreeData[i].key;
|
||||
currentRowHeight = 0;
|
||||
if (this.firstLevelKey.indexOf(currentKey) >= 0 || this.expandChildRowKeys.indexOf(currentKey) >= 0) {
|
||||
if (this.flatTreeKeysMap.hasOwnProperty(currentKey)) {
|
||||
currentRowHeight = rowHeight;
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +309,10 @@ function bigData(Table) {
|
|||
var data = this.props.data;
|
||||
var scrollTop = this.scrollTop;
|
||||
var endIndex = this.endIndex,
|
||||
startIndex = this.startIndex;
|
||||
startIndex = this.startIndex,
|
||||
treeData = this.treeData,
|
||||
treeType = this.treeType,
|
||||
flatTreeData = this.flatTreeData;
|
||||
|
||||
var expandedRowKeys = this.props.expandedRowKeys ? this.props.expandedRowKeys : this.expandedRowKeys;
|
||||
if (startIndex < 0) {
|
||||
|
@ -281,34 +321,44 @@ function bigData(Table) {
|
|||
if (endIndex < 0) {
|
||||
endIndex = 0;
|
||||
}
|
||||
if (endIndex > data.length) {
|
||||
endIndex = data.length;
|
||||
if (treeType && endIndex > flatTreeData.length || !treeType && endIndex > data.length) {
|
||||
endIndex = treeType ? flatTreeData.length : data.length;
|
||||
}
|
||||
var lazyLoad = {
|
||||
startIndex: startIndex,
|
||||
endIndex: endIndex,
|
||||
startParentIndex: startIndex //为树状节点做准备
|
||||
};
|
||||
if (this.treeType) {
|
||||
var preSubCounts = this.cachedRowParentIndex.findIndex(function (item) {
|
||||
return item == startIndex;
|
||||
});
|
||||
var sufSubCounts = this.cachedRowParentIndex.findIndex(function (item) {
|
||||
return item == endIndex;
|
||||
});
|
||||
lazyLoad.preHeight = this.getSumHeight(0, preSubCounts > -1 ? preSubCounts : 0);
|
||||
lazyLoad.sufHeight = this.getSumHeight(sufSubCounts + 1 > 0 ? sufSubCounts + 1 : this.cachedRowParentIndex.length, this.cachedRowParentIndex.length);
|
||||
if (treeType) {
|
||||
// const preSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
// return item == startIndex;
|
||||
// });
|
||||
// const sufSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
// return item == endIndex;
|
||||
// });
|
||||
// lazyLoad.preHeight = this.getSumHeight(
|
||||
// 0,
|
||||
// preSubCounts > -1 ? preSubCounts : 0
|
||||
// );
|
||||
// lazyLoad.sufHeight = this.getSumHeight(
|
||||
// sufSubCounts + 1 > 0
|
||||
// ? sufSubCounts + 1
|
||||
// : this.cachedRowParentIndex.length,
|
||||
// this.cachedRowParentIndex.length
|
||||
// );
|
||||
|
||||
if (preSubCounts > 0) {
|
||||
lazyLoad.startIndex = preSubCounts;
|
||||
}
|
||||
// if (preSubCounts > 0) {
|
||||
// lazyLoad.startIndex = preSubCounts;
|
||||
// }
|
||||
lazyLoad.preHeight = this.getSumHeight(0, startIndex);
|
||||
lazyLoad.sufHeight = this.getSumHeight(endIndex, flatTreeData.length);
|
||||
} else {
|
||||
lazyLoad.preHeight = this.getSumHeight(0, startIndex);
|
||||
lazyLoad.sufHeight = this.getSumHeight(endIndex, data.length);
|
||||
}
|
||||
// console.log('*******expandedRowKeys*****'+expandedRowKeys);
|
||||
return _react2["default"].createElement(Table, _extends({}, this.props, {
|
||||
data: data.slice(startIndex, endIndex),
|
||||
data: Array.isArray(treeData) && treeData.length > 0 ? treeData : data.slice(startIndex, endIndex),
|
||||
lazyLoad: lazyLoad,
|
||||
handleScrollY: this.handleScrollY,
|
||||
scrollTop: scrollTop,
|
||||
|
@ -336,6 +386,66 @@ function bigData(Table) {
|
|||
}, _initialiseProps = function _initialiseProps() {
|
||||
var _this4 = this;
|
||||
|
||||
this.deepTraversal = function (treeData) {
|
||||
var parentKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||||
var isShown = arguments[2];
|
||||
|
||||
var _this = _this4;
|
||||
var cacheExpandedKeys = _this.cacheExpandedKeys,
|
||||
_this$expandedRowKeys = _this.expandedRowKeys,
|
||||
expandedRowKeys = _this$expandedRowKeys === undefined ? [] : _this$expandedRowKeys,
|
||||
flatTreeKeysMap = _this.flatTreeKeysMap,
|
||||
flatTreeData = [],
|
||||
dataCopy = treeData;
|
||||
|
||||
if (Array.isArray(dataCopy)) {
|
||||
for (var i = 0, l = dataCopy.length; i < l; i++) {
|
||||
var _dataCopy$i = dataCopy[i],
|
||||
key = _dataCopy$i.key,
|
||||
children = _dataCopy$i.children,
|
||||
props = _objectWithoutProperties(_dataCopy$i, ["key", "children"]);
|
||||
|
||||
var dataCopyI = new Object();
|
||||
var isLeaf = children ? false : true,
|
||||
isExpanded = cacheExpandedKeys ? cacheExpandedKeys.indexOf(key) !== -1 : expandedRowKeys.indexOf(key) !== -1;
|
||||
dataCopyI = _extends(dataCopyI, {
|
||||
key: key,
|
||||
isExpanded: isExpanded,
|
||||
parentKey: parentKey,
|
||||
isShown: isShown,
|
||||
isLeaf: isLeaf,
|
||||
index: flatTreeData.length
|
||||
}, _extends({}, props));
|
||||
//该节点的父节点是展开状态 或 该节点是根节点
|
||||
if (isShown || parentKey === null) {
|
||||
flatTreeData.push(dataCopyI); // 取每项数据放入一个新数组
|
||||
flatTreeKeysMap[key] = dataCopyI;
|
||||
}
|
||||
if (Array.isArray(children) && children.length > 0) {
|
||||
// 若存在children则递归调用,把数据拼接到新数组中,并且删除该children
|
||||
flatTreeData = flatTreeData.concat(_this4.deepTraversal(children, key, isExpanded));
|
||||
}
|
||||
}
|
||||
}
|
||||
return flatTreeData;
|
||||
};
|
||||
|
||||
this.handleTreeListChange = function (treeList, startIndex, endIndex) {
|
||||
// 属性配置设置
|
||||
var attr = {
|
||||
id: 'key',
|
||||
parendId: 'parentKey',
|
||||
rootId: null,
|
||||
isLeaf: 'isLeaf'
|
||||
};
|
||||
var treeData = (0, _utils.convertListToTree)(treeList, attr, _this4.flatTreeKeysMap);
|
||||
|
||||
_this4.startIndex = typeof startIndex !== "undefined" ? startIndex : _this4.startIndex;
|
||||
_this4.endIndex = typeof endIndex !== "undefined" ? endIndex : _this4.endIndex;
|
||||
|
||||
_this4.treeData = treeData;
|
||||
};
|
||||
|
||||
this.computeCachedRowParentIndex = function (data) {
|
||||
var isTree = _this4.props.isTree;
|
||||
|
||||
|
@ -373,7 +483,8 @@ function bigData(Table) {
|
|||
currentIndex = _this$currentIndex === undefined ? 0 : _this$currentIndex,
|
||||
loadCount = _this.loadCount,
|
||||
scrollTop = _this.scrollTop,
|
||||
currentScrollTop = _this.currentScrollTop;
|
||||
currentScrollTop = _this.currentScrollTop,
|
||||
flatTreeData = _this.flatTreeData;
|
||||
var endIndex = _this.endIndex,
|
||||
startIndex = _this.startIndex;
|
||||
var needRender = _this.state.needRender;
|
||||
|
@ -388,9 +499,10 @@ function bigData(Table) {
|
|||
var currentRowHeight = _this4.cachedRowHeight[index];
|
||||
if (currentRowHeight === undefined) {
|
||||
if (_this4.treeType) {
|
||||
currentKey = _this4.keys[index];
|
||||
// currentKey = this.keys[index];
|
||||
currentKey = _this4.flatTreeData[index].key;
|
||||
currentRowHeight = 0;
|
||||
if (_this4.firstLevelKey.indexOf(currentKey) >= 0 || _this4.expandChildRowKeys.indexOf(currentKey) >= 0) {
|
||||
if (_this4.flatTreeKeysMap.hasOwnProperty(currentKey)) {
|
||||
currentRowHeight = rowHeight;
|
||||
}
|
||||
} else {
|
||||
|
@ -418,21 +530,25 @@ function bigData(Table) {
|
|||
while (rowsHeight < viewHeight && tempIndex < _this4.cachedRowHeight.length) {
|
||||
if (_this4.cachedRowHeight[tempIndex]) {
|
||||
rowsHeight += _this4.cachedRowHeight[tempIndex];
|
||||
if (treeType && _this.cachedRowParentIndex[tempIndex] !== tempIndex || !treeType) {
|
||||
rowsInView++;
|
||||
}
|
||||
// if (
|
||||
// (treeType &&
|
||||
// _this.cachedRowParentIndex[tempIndex] !== tempIndex) ||
|
||||
// !treeType
|
||||
// ) {
|
||||
rowsInView++;
|
||||
// }
|
||||
}
|
||||
tempIndex++;
|
||||
}
|
||||
if (treeType) {
|
||||
var treeIndex = index;
|
||||
index = _this.cachedRowParentIndex[treeIndex];
|
||||
if (index === undefined) {
|
||||
// console.log('index is undefined********'+treeIndex);
|
||||
index = _this4.getParentIndex(treeIndex);
|
||||
// console.log("getParentIndex****"+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则重新渲染
|
||||
|
@ -440,12 +556,15 @@ function bigData(Table) {
|
|||
startIndex = index - loadBuffer > 0 ? index - loadBuffer : 0;
|
||||
// endIndex = startIndex + rowsInView + loadBuffer*2;
|
||||
endIndex = startIndex + loadCount;
|
||||
if (endIndex > data.length) {
|
||||
endIndex = data.length;
|
||||
if (treeType && endIndex > flatTreeData.length || !treeType && endIndex > data.length) {
|
||||
endIndex = treeType ? flatTreeData.length : data.length;
|
||||
}
|
||||
if (endIndex > _this4.endIndex) {
|
||||
_this4.startIndex = startIndex;
|
||||
_this4.endIndex = endIndex;
|
||||
if (treeType) {
|
||||
_this4.handleTreeListChange(flatTreeData.slice(startIndex, endIndex), startIndex, endIndex);
|
||||
}
|
||||
_this4.setState({ needRender: !needRender });
|
||||
callback(parseInt(currentIndex + rowsInView));
|
||||
}
|
||||
|
@ -459,6 +578,9 @@ function bigData(Table) {
|
|||
if (startIndex < _this4.startIndex) {
|
||||
_this4.startIndex = startIndex;
|
||||
_this4.endIndex = _this4.startIndex + loadCount;
|
||||
if (treeType) {
|
||||
_this4.handleTreeListChange(flatTreeData.slice(startIndex, _this4.endIndex), startIndex, _this4.endIndex);
|
||||
}
|
||||
_this4.setState({ needRender: !needRender });
|
||||
callback(parseInt(currentIndex + rowsInView));
|
||||
}
|
||||
|
@ -474,9 +596,10 @@ function bigData(Table) {
|
|||
|
||||
this.onExpand = function (expandState, record, index) {
|
||||
var _this = _this4;
|
||||
var _this$expandedRowKeys = _this.expandedRowKeys,
|
||||
expandedRowKeys = _this$expandedRowKeys === undefined ? [] : _this$expandedRowKeys;
|
||||
var _this$expandedRowKeys2 = _this.expandedRowKeys,
|
||||
expandedRowKeys = _this$expandedRowKeys2 === undefined ? [] : _this$expandedRowKeys2;
|
||||
var needRender = _this.state.needRender;
|
||||
var data = _this.props.data;
|
||||
|
||||
var rowKey = _this.getRowKey(record, index);
|
||||
// 记录展开子表行的key
|
||||
|
@ -514,6 +637,17 @@ function bigData(Table) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_this4.treeType) {
|
||||
//收起和展开时,缓存 expandedKeys
|
||||
_this.cacheExpandedKeys = expandedRowKeys;
|
||||
//重新递归数据
|
||||
var flatTreeData = _this.deepTraversal(data);
|
||||
var sliceTreeList = flatTreeData.slice(_this.startIndex, _this.endIndex);
|
||||
_this.flatTreeData = flatTreeData;
|
||||
_this.handleTreeListChange(sliceTreeList);
|
||||
_this.cacheExpandedKeys = null;
|
||||
}
|
||||
|
||||
// expandState为true时,记录下
|
||||
_this.props.onExpand(expandState, record);
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ exports.getColChildrenLength = getColChildrenLength;
|
|||
exports.DicimalFormater = DicimalFormater;
|
||||
exports.checkDicimalInvalid = checkDicimalInvalid;
|
||||
exports.formatMoney = formatMoney;
|
||||
exports.convertListToTree = convertListToTree;
|
||||
|
||||
var _warning = require('warning');
|
||||
|
||||
|
@ -31,6 +32,8 @@ var _parseInt2 = _interopRequireDefault(_parseInt);
|
|||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
||||
|
||||
var scrollbarSize = void 0;
|
||||
|
||||
// Measure scrollbar width for padding body during modal show/hide
|
||||
|
@ -333,4 +336,105 @@ var Event = exports.Event = {
|
|||
getTarget: getTarget,
|
||||
preventDefault: preventDefault,
|
||||
stopPropagation: stopPropagation
|
||||
};
|
||||
|
||||
/**
|
||||
* 将一维数组转换为树结构
|
||||
* @param {*} treeData 扁平结构的 List 数组
|
||||
* @param {*} attr 属性配置设置
|
||||
* @param {*} flatTreeKeysMap 存储所有 key-value 的映射,方便获取各节点信息
|
||||
*/
|
||||
};function convertListToTree(treeData, attr, flatTreeKeysMap) {
|
||||
var tree = []; //存储所有一级节点
|
||||
var resData = treeData,
|
||||
//resData 存储截取的节点 + 父节点(除一级节点外)
|
||||
resKeysMap = {},
|
||||
//resData 的Map映射
|
||||
treeKeysMap = {}; //tree 的Map映射
|
||||
resData.map(function (element) {
|
||||
var key = attr.id;
|
||||
resKeysMap[element[key]] = element;
|
||||
});
|
||||
// 查找父节点,为了补充不完整的数据结构
|
||||
var findParentNode = function findParentNode(node) {
|
||||
var parentKey = node[attr.parendId];
|
||||
if (parentKey !== attr.rootId) {
|
||||
//如果不是根节点,则继续递归
|
||||
var item = flatTreeKeysMap[parentKey];
|
||||
// 用 resKeysMap 判断,避免重复计算某节点的父节点
|
||||
if (resKeysMap.hasOwnProperty(item[attr.id])) return;
|
||||
resData.unshift(item);
|
||||
resKeysMap[item[attr.id]] = item;
|
||||
findParentNode(item);
|
||||
} else {
|
||||
// 用 treeKeysMap 判断,避免重复累加
|
||||
if (!treeKeysMap.hasOwnProperty(node[attr.id])) {
|
||||
var key = node.key,
|
||||
title = node.title,
|
||||
children = node.children,
|
||||
isLeaf = node.isLeaf,
|
||||
otherProps = _objectWithoutProperties(node, ['key', 'title', 'children', 'isLeaf']);
|
||||
|
||||
var obj = {
|
||||
key: key,
|
||||
title: title,
|
||||
isLeaf: isLeaf,
|
||||
children: []
|
||||
};
|
||||
tree.push(_extends(obj, _extends({}, otherProps)));
|
||||
treeKeysMap[key] = node;
|
||||
}
|
||||
}
|
||||
};
|
||||
// 遍历 resData ,找到所有的一级节点
|
||||
for (var i = 0; i < resData.length; i++) {
|
||||
var item = resData[i];
|
||||
if (item[attr.parendId] === attr.rootId && !treeKeysMap.hasOwnProperty(item[attr.id])) {
|
||||
//如果是根节点,就存放进 tree 对象中
|
||||
var key = item.key,
|
||||
title = item.title,
|
||||
children = item.children,
|
||||
otherProps = _objectWithoutProperties(item, ['key', 'title', 'children']);
|
||||
|
||||
var obj = {
|
||||
key: item[attr.id],
|
||||
isLeaf: item[attr.isLeaf],
|
||||
children: []
|
||||
};
|
||||
tree.push(_extends(obj, _extends({}, otherProps)));
|
||||
treeKeysMap[key] = item;
|
||||
resData.splice(i, 1);
|
||||
i--;
|
||||
} else {
|
||||
//递归查找根节点信息
|
||||
findParentNode(item);
|
||||
}
|
||||
}
|
||||
// console.log('resData',resKeysMap);
|
||||
var run = function run(treeArrs) {
|
||||
if (resData.length > 0) {
|
||||
for (var _i = 0; _i < treeArrs.length; _i++) {
|
||||
for (var j = 0; j < resData.length; j++) {
|
||||
var _item = resData[j];
|
||||
if (treeArrs[_i].key === _item[attr.parendId]) {
|
||||
var _key = _item.key,
|
||||
_title = _item.title,
|
||||
_children = _item.children,
|
||||
_otherProps = _objectWithoutProperties(_item, ['key', 'title', 'children']);
|
||||
|
||||
var _obj = {
|
||||
key: _item[attr.id],
|
||||
isLeaf: _item[attr.isLeaf],
|
||||
children: []
|
||||
};
|
||||
treeArrs[_i].children.push(_extends(_obj, _extends({}, _otherProps)));
|
||||
resData.splice(j, 1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
run(treeArrs[_i].children);
|
||||
}
|
||||
}
|
||||
};
|
||||
run(tree);
|
||||
return tree;
|
||||
}
|
|
@ -17,7 +17,8 @@ const columns = [
|
|||
width:'150',
|
||||
key:'index',
|
||||
render:(text,record,index)=>{
|
||||
return index
|
||||
//树形表格,可取 record.index 作为序号索引值
|
||||
return record.index
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -48,6 +49,10 @@ const data = [ ...new Array(1000) ].map((e, i) => {
|
|||
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`});
|
||||
rs.children[subi].children = []
|
||||
for(let subj=0;subj<100;subj++){
|
||||
rs.children[subi].children.push({a: 333+' '+subj, b: 333+' '+subj, c: 333+' '+subj, d: 333+' '+subj, key: i+ `${subj} sub1`});
|
||||
}
|
||||
}
|
||||
}else{
|
||||
rs.children = [];
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -710,7 +710,8 @@ class Table extends Component {
|
|||
// }
|
||||
const record = data[i];
|
||||
const key = this.getRowKey(record, i);
|
||||
const childrenColumn = record[childrenColumnName];
|
||||
const isLeaf = typeof record['isLeaf'] === 'boolean' && record['isLeaf'] || false;
|
||||
const childrenColumn = isLeaf ? false : record[childrenColumnName];
|
||||
const isRowExpanded = this.isRowExpanded(record, i);
|
||||
let expandedRowContent;
|
||||
let expandedContentHeight = 0;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { convertListToTree } from "./utils";
|
||||
const defaultHeight = 30;
|
||||
const rowDiff = 2; //行差值
|
||||
let treeTypeIndex = 0;
|
||||
|
@ -43,6 +44,9 @@ export default function bigData(Table) {
|
|||
this.setRowHeight = this.setRowHeight.bind(this);
|
||||
this.setRowParentIndex = this.setRowParentIndex.bind(this);
|
||||
this.expandedRowKeys = [];
|
||||
this.flatTreeKeysMap = {}; //树表,扁平结构数据的 Map 映射,方便获取各节点信息
|
||||
this.flatTreeData = []; //深度遍历处理后的data数组
|
||||
this.treeData = []; //树表的data数据
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const props = this.props;
|
||||
|
@ -76,9 +80,79 @@ export default function bigData(Table) {
|
|||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { data } = this.props;
|
||||
componentWillMount() {
|
||||
let { endIndex, startIndex } = this;
|
||||
let sliceTreeList = [];
|
||||
const { data,isTree } = this.props;
|
||||
const isTreeType = isTree?true:this.checkIsTreeType();
|
||||
//设置data中每个元素的parentIndex
|
||||
this.computeCachedRowParentIndex(data);
|
||||
//如果是树表,递归data
|
||||
if(isTreeType){
|
||||
this.treeType = isTreeType;
|
||||
let flatTreeData = this.deepTraversal(data);
|
||||
sliceTreeList = flatTreeData.slice(startIndex, endIndex);
|
||||
this.flatTreeData = flatTreeData;
|
||||
this.handleTreeListChange(sliceTreeList);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 深度遍历树形 data,把数据拍平,变为一维数组
|
||||
* @param {*} data
|
||||
* @param {*} parentKey 标识父节点
|
||||
* @param {*} isShown 该节点是否显示在页面中,当节点的父节点是展开状态 或 该节点是根节点时,该值为 true
|
||||
*/
|
||||
deepTraversal = (treeData, parentKey=null, isShown) => {
|
||||
const _this = this;
|
||||
let {cacheExpandedKeys, expandedRowKeys = [], flatTreeKeysMap} = _this,
|
||||
flatTreeData = [],
|
||||
dataCopy = treeData;
|
||||
if(Array.isArray(dataCopy)){
|
||||
for (let i=0, l=dataCopy.length; i<l; i++) {
|
||||
let { key, children, ...props } = dataCopy[i];
|
||||
let dataCopyI = new Object();
|
||||
let isLeaf = children ? false : true,
|
||||
isExpanded = cacheExpandedKeys ? cacheExpandedKeys.indexOf(key) !== -1 : expandedRowKeys.indexOf(key) !== -1;
|
||||
dataCopyI = Object.assign(dataCopyI,{
|
||||
key,
|
||||
isExpanded,
|
||||
parentKey : parentKey,
|
||||
isShown,
|
||||
isLeaf,
|
||||
index: flatTreeData.length
|
||||
},{...props});
|
||||
//该节点的父节点是展开状态 或 该节点是根节点
|
||||
if(isShown || parentKey === null){
|
||||
flatTreeData.push(dataCopyI); // 取每项数据放入一个新数组
|
||||
flatTreeKeysMap[key] = dataCopyI;
|
||||
}
|
||||
if (Array.isArray(children) && children.length > 0){
|
||||
// 若存在children则递归调用,把数据拼接到新数组中,并且删除该children
|
||||
flatTreeData = flatTreeData.concat(this.deepTraversal(children, key, isExpanded));
|
||||
}
|
||||
}
|
||||
}
|
||||
return flatTreeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将截取后的 List 数组转换为 Tree 结构,并更新 state
|
||||
*/
|
||||
handleTreeListChange = (treeList, startIndex, endIndex) => {
|
||||
// 属性配置设置
|
||||
let attr = {
|
||||
id: 'key',
|
||||
parendId: 'parentKey',
|
||||
rootId: null,
|
||||
isLeaf: 'isLeaf'
|
||||
};
|
||||
let treeData = convertListToTree(treeList, attr, this.flatTreeKeysMap);
|
||||
|
||||
this.startIndex = typeof(startIndex) !== "undefined" ? startIndex : this.startIndex;
|
||||
this.endIndex = typeof(endIndex) !== "undefined" ? endIndex : this.endIndex;
|
||||
|
||||
this.treeData = treeData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,11 +265,11 @@ export default function bigData(Table) {
|
|||
for (let i = start; i < end; i++) {
|
||||
if (this.cachedRowHeight[i] == undefined) {
|
||||
if (this.treeType) {
|
||||
currentKey = this.keys[i];
|
||||
// currentKey = this.keys[i];
|
||||
currentKey = this.flatTreeData[i].key;
|
||||
currentRowHeight = 0;
|
||||
if (
|
||||
this.firstLevelKey.indexOf(currentKey) >= 0 ||
|
||||
this.expandChildRowKeys.indexOf(currentKey) >= 0
|
||||
this.flatTreeKeysMap.hasOwnProperty(currentKey)
|
||||
) {
|
||||
currentRowHeight = rowHeight;
|
||||
}
|
||||
|
@ -226,7 +300,8 @@ export default function bigData(Table) {
|
|||
currentIndex = 0,
|
||||
loadCount,
|
||||
scrollTop,
|
||||
currentScrollTop
|
||||
currentScrollTop,
|
||||
flatTreeData
|
||||
} = _this;
|
||||
let { endIndex, startIndex } = _this;
|
||||
const { needRender } = _this.state;
|
||||
|
@ -240,11 +315,11 @@ export default function bigData(Table) {
|
|||
let currentRowHeight = this.cachedRowHeight[index];
|
||||
if (currentRowHeight === undefined) {
|
||||
if (this.treeType) {
|
||||
currentKey = this.keys[index];
|
||||
// currentKey = this.keys[index];
|
||||
currentKey = this.flatTreeData[index].key;
|
||||
currentRowHeight = 0;
|
||||
if (
|
||||
this.firstLevelKey.indexOf(currentKey) >= 0 ||
|
||||
this.expandChildRowKeys.indexOf(currentKey) >= 0
|
||||
this.flatTreeKeysMap.hasOwnProperty(currentKey)
|
||||
) {
|
||||
currentRowHeight = rowHeight;
|
||||
}
|
||||
|
@ -276,25 +351,25 @@ export default function bigData(Table) {
|
|||
) {
|
||||
if (this.cachedRowHeight[tempIndex]) {
|
||||
rowsHeight += this.cachedRowHeight[tempIndex];
|
||||
if (
|
||||
(treeType &&
|
||||
_this.cachedRowParentIndex[tempIndex] !== tempIndex) ||
|
||||
!treeType
|
||||
) {
|
||||
// if (
|
||||
// (treeType &&
|
||||
// _this.cachedRowParentIndex[tempIndex] !== tempIndex) ||
|
||||
// !treeType
|
||||
// ) {
|
||||
rowsInView++;
|
||||
}
|
||||
// }
|
||||
}
|
||||
tempIndex++;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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则重新渲染
|
||||
|
@ -302,12 +377,15 @@ export default function bigData(Table) {
|
|||
startIndex = index - loadBuffer > 0 ? index - loadBuffer : 0;
|
||||
// endIndex = startIndex + rowsInView + loadBuffer*2;
|
||||
endIndex = startIndex + loadCount;
|
||||
if (endIndex > data.length) {
|
||||
endIndex = data.length;
|
||||
if (treeType && endIndex > flatTreeData.length || !treeType && endIndex > data.length) {
|
||||
endIndex = treeType ? flatTreeData.length : data.length;
|
||||
}
|
||||
if (endIndex > this.endIndex ) {
|
||||
this.startIndex = startIndex;
|
||||
this.endIndex = endIndex;
|
||||
if(treeType) {
|
||||
this.handleTreeListChange(flatTreeData.slice(startIndex,endIndex), startIndex, endIndex)
|
||||
}
|
||||
this.setState({ needRender: !needRender });
|
||||
callback(parseInt(currentIndex + rowsInView));
|
||||
}
|
||||
|
@ -321,6 +399,9 @@ export default function bigData(Table) {
|
|||
if (startIndex < this.startIndex) {
|
||||
this.startIndex = startIndex;
|
||||
this.endIndex = this.startIndex + loadCount;
|
||||
if(treeType) {
|
||||
this.handleTreeListChange(flatTreeData.slice(startIndex,this.endIndex), startIndex, this.endIndex)
|
||||
}
|
||||
this.setState({ needRender: !needRender });
|
||||
callback(parseInt(currentIndex + rowsInView));
|
||||
}
|
||||
|
@ -373,6 +454,7 @@ export default function bigData(Table) {
|
|||
const _this = this;
|
||||
let {expandedRowKeys = []} = _this;
|
||||
const {needRender} = _this.state;
|
||||
const { data } = _this.props;
|
||||
const rowKey = _this.getRowKey(record, index);
|
||||
// 记录展开子表行的key
|
||||
// 展开
|
||||
|
@ -413,6 +495,16 @@ export default function bigData(Table) {
|
|||
}
|
||||
}
|
||||
|
||||
if(this.treeType) {
|
||||
//收起和展开时,缓存 expandedKeys
|
||||
_this.cacheExpandedKeys = expandedRowKeys;
|
||||
//重新递归数据
|
||||
let flatTreeData = _this.deepTraversal(data);
|
||||
let sliceTreeList = flatTreeData.slice(_this.startIndex, _this.endIndex);
|
||||
_this.flatTreeData = flatTreeData;
|
||||
_this.handleTreeListChange(sliceTreeList);
|
||||
_this.cacheExpandedKeys = null;
|
||||
}
|
||||
|
||||
// expandState为true时,记录下
|
||||
_this.props.onExpand(expandState, record);
|
||||
|
@ -422,7 +514,7 @@ export default function bigData(Table) {
|
|||
render() {
|
||||
const { data } = this.props;
|
||||
const { scrollTop } = this;
|
||||
let { endIndex, startIndex } = this;
|
||||
let { endIndex, startIndex, treeData, treeType, flatTreeData } = this;
|
||||
let expandedRowKeys = this.props.expandedRowKeys?this.props.expandedRowKeys: this.expandedRowKeys;
|
||||
if(startIndex < 0){
|
||||
startIndex = 0;
|
||||
|
@ -430,35 +522,37 @@ export default function bigData(Table) {
|
|||
if(endIndex < 0 ){
|
||||
endIndex = 0;
|
||||
}
|
||||
if(endIndex > data.length){
|
||||
endIndex = data.length;
|
||||
if (treeType && endIndex > flatTreeData.length || !treeType && endIndex > data.length) {
|
||||
endIndex = treeType ? flatTreeData.length : data.length;
|
||||
}
|
||||
const lazyLoad = {
|
||||
startIndex: startIndex,
|
||||
endIndex:endIndex,
|
||||
startParentIndex: startIndex //为树状节点做准备
|
||||
};
|
||||
if (this.treeType) {
|
||||
const preSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
return item == startIndex;
|
||||
});
|
||||
const sufSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
return item == endIndex;
|
||||
});
|
||||
lazyLoad.preHeight = this.getSumHeight(
|
||||
0,
|
||||
preSubCounts > -1 ? preSubCounts : 0
|
||||
);
|
||||
lazyLoad.sufHeight = this.getSumHeight(
|
||||
sufSubCounts + 1 > 0
|
||||
? sufSubCounts + 1
|
||||
: this.cachedRowParentIndex.length,
|
||||
this.cachedRowParentIndex.length
|
||||
);
|
||||
if (treeType) {
|
||||
// const preSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
// return item == startIndex;
|
||||
// });
|
||||
// const sufSubCounts = this.cachedRowParentIndex.findIndex(item => {
|
||||
// return item == endIndex;
|
||||
// });
|
||||
// lazyLoad.preHeight = this.getSumHeight(
|
||||
// 0,
|
||||
// preSubCounts > -1 ? preSubCounts : 0
|
||||
// );
|
||||
// lazyLoad.sufHeight = this.getSumHeight(
|
||||
// sufSubCounts + 1 > 0
|
||||
// ? sufSubCounts + 1
|
||||
// : this.cachedRowParentIndex.length,
|
||||
// this.cachedRowParentIndex.length
|
||||
// );
|
||||
|
||||
if (preSubCounts > 0) {
|
||||
lazyLoad.startIndex = preSubCounts;
|
||||
}
|
||||
// if (preSubCounts > 0) {
|
||||
// lazyLoad.startIndex = preSubCounts;
|
||||
// }
|
||||
lazyLoad.preHeight = this.getSumHeight(0, startIndex);
|
||||
lazyLoad.sufHeight = this.getSumHeight(endIndex, flatTreeData.length);
|
||||
} else {
|
||||
lazyLoad.preHeight = this.getSumHeight(0, startIndex);
|
||||
lazyLoad.sufHeight = this.getSumHeight(endIndex, data.length);
|
||||
|
@ -467,7 +561,7 @@ export default function bigData(Table) {
|
|||
return (
|
||||
<Table
|
||||
{...this.props}
|
||||
data={data.slice(startIndex, endIndex)}
|
||||
data={Array.isArray(treeData) && treeData.length > 0 ? treeData : data.slice(startIndex, endIndex)}
|
||||
lazyLoad={lazyLoad}
|
||||
handleScrollY={this.handleScrollY}
|
||||
scrollTop={scrollTop}
|
||||
|
|
|
@ -317,4 +317,88 @@ export const Event = {
|
|||
getTarget,
|
||||
preventDefault,
|
||||
stopPropagation
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一维数组转换为树结构
|
||||
* @param {*} treeData 扁平结构的 List 数组
|
||||
* @param {*} attr 属性配置设置
|
||||
* @param {*} flatTreeKeysMap 存储所有 key-value 的映射,方便获取各节点信息
|
||||
*/
|
||||
export function convertListToTree(treeData, attr, flatTreeKeysMap) {
|
||||
let tree = []; //存储所有一级节点
|
||||
let resData = treeData, //resData 存储截取的节点 + 父节点(除一级节点外)
|
||||
resKeysMap = {}, //resData 的Map映射
|
||||
treeKeysMap = {}; //tree 的Map映射
|
||||
resData.map((element) => {
|
||||
let key = attr.id;
|
||||
resKeysMap[element[key]] = element;
|
||||
});
|
||||
// 查找父节点,为了补充不完整的数据结构
|
||||
let findParentNode = (node) => {
|
||||
let parentKey = node[attr.parendId];
|
||||
if(parentKey !== attr.rootId) { //如果不是根节点,则继续递归
|
||||
let item = flatTreeKeysMap[parentKey];
|
||||
// 用 resKeysMap 判断,避免重复计算某节点的父节点
|
||||
if(resKeysMap.hasOwnProperty(item[attr.id])) return;
|
||||
resData.unshift(item);
|
||||
resKeysMap[item[attr.id]] = item;
|
||||
findParentNode(item);
|
||||
}else{
|
||||
// 用 treeKeysMap 判断,避免重复累加
|
||||
if (!treeKeysMap.hasOwnProperty(node[attr.id]) ) {
|
||||
let { key, title, children, isLeaf, ...otherProps } = node;
|
||||
let obj = {
|
||||
key,
|
||||
title,
|
||||
isLeaf,
|
||||
children: []
|
||||
}
|
||||
tree.push(Object.assign(obj, {...otherProps}));
|
||||
treeKeysMap[key] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 遍历 resData ,找到所有的一级节点
|
||||
for (let i = 0; i < resData.length; i++) {
|
||||
let item = resData[i];
|
||||
if (item[attr.parendId] === attr.rootId && !treeKeysMap.hasOwnProperty(item[attr.id])) { //如果是根节点,就存放进 tree 对象中
|
||||
let { key, title, children, ...otherProps } = item;
|
||||
let obj = {
|
||||
key: item[attr.id],
|
||||
isLeaf: item[attr.isLeaf],
|
||||
children: []
|
||||
};
|
||||
tree.push(Object.assign(obj, {...otherProps}));
|
||||
treeKeysMap[key] = item;
|
||||
resData.splice(i, 1);
|
||||
i--;
|
||||
}else { //递归查找根节点信息
|
||||
findParentNode(item);
|
||||
}
|
||||
}
|
||||
// console.log('resData',resKeysMap);
|
||||
var run = function(treeArrs) {
|
||||
if (resData.length > 0) {
|
||||
for (let i = 0; i < treeArrs.length; i++) {
|
||||
for (let j = 0; j < resData.length; j++) {
|
||||
let item = resData[j];
|
||||
if (treeArrs[i].key === item[attr.parendId]) {
|
||||
let { key, title, children, ...otherProps } = item;
|
||||
let obj = {
|
||||
key: item[attr.id],
|
||||
isLeaf: item[attr.isLeaf],
|
||||
children: []
|
||||
};
|
||||
treeArrs[i].children.push(Object.assign(obj, {...otherProps}));
|
||||
resData.splice(j, 1);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
run(treeArrs[i].children);
|
||||
}
|
||||
}
|
||||
};
|
||||
run(tree);
|
||||
return tree;
|
||||
}
|
Loading…
Reference in New Issue