UNPKG

@uiw/react-native

Version:
226 lines (213 loc) 5.61 kB
/** * 平铺树节点使节点可以进行遍历 */ export function flattenTreeData(treeNodeList = [], expandedKeys = []) { const expandedKeySet = new Set(expandedKeys === true ? [] : expandedKeys); const flattenList = []; //递归遍历每一个节点 function dig(list, parent = null, show) { return list.map(treeNode => { const mergedKey = treeNode.value; const flattenNode = { ...treeNode, show, parent, children: null, data: treeNode, key: mergedKey }; flattenList.push(flattenNode); // 遍历子节点 if ((expandedKeys === true || expandedKeySet.has(mergedKey.toString())) && show === true) { flattenNode.children = dig(treeNode.children || [], flattenNode, true); } else { flattenNode.children = dig(treeNode.children || [], flattenNode, false); } return flattenNode; }); } dig(treeNodeList, null, true); return flattenList; } export function arrDel(list, value) { const clone = list.slice(); const index = clone.indexOf(value); if (index >= 0) { clone.splice(index, 1); } return clone; } export function arrAdd(list, value) { const clone = list.slice(); if (clone.indexOf(value) === -1) { clone.push(value); } return clone; } /** * 获取树组件的props */ export function getTreeNodeProps(key, { expandedKeys, checkedKeys }) { const treeNodeProps = { eventKey: key, expanded: expandedKeys.indexOf(key) !== -1, checked: checkedKeys.indexOf(key) !== -1 }; return treeNodeProps; } /** * 获取节点的数据 * 用对象形式可以快速查找响应节点 */ export function getTreeNodeLevel(treeData = []) { const nodeLevel = {}; function processNode(node, parent) { const children = node ? node.children : treeData; if (node) { nodeLevel[node.value] = { level: parent ? parent.level + 1 : 0, parent: parent, children: children, data: node, value: node.value }; } if (children) { children.forEach(subNode => { processNode(subNode, node ? nodeLevel[node?.value] : null); }); } } processNode(null, null); return nodeLevel; } /** * 填充选中的节点 */ function fillConductCheck(keys, levelEntities, maxLevel) { const checkedKeys = new Set(keys); // 从顶部到底部添加选中的键 for (let level = 0; level <= maxLevel; level += 1) { const entities = levelEntities.get(level) || new Set(); entities.forEach(entity => { const { key, children = [] } = entity; if (checkedKeys.has(key)) { children?.forEach(childEntity => { checkedKeys.add(childEntity.value); }); } }); } // 从下至上添加选中的键 const visitedKeys = new Set(); for (let level = maxLevel; level > 0; level -= 1) { const entities = levelEntities.get(level) || new Set(); entities.forEach(entity => { const { parent } = entity; let allChecked = true; (parent?.children || []).forEach(({ value }) => { const checked = checkedKeys.has(value); if (allChecked && !checked) { allChecked = false; } }); if (allChecked) { checkedKeys.add(parent.value); } visitedKeys.add(parent.value); }); } return Array.from(checkedKeys); } /** * 移除取消的节点 */ function cleanConductCheck(keys, levelEntities, maxLevel) { const checkedKeys = new Set(keys); // 从上到下删除选中的键 for (let level = 0; level <= maxLevel; level += 1) { const entities = levelEntities.get(level) || new Set(); entities.forEach(entity => { const { key, children = [] } = entity; if (!checkedKeys.has(key)) { children?.forEach(childEntity => { checkedKeys.delete(childEntity.value); }); } }); } // 从下到上删除选中的键 const visitedKeys = new Set(); for (let level = maxLevel; level > 0; level -= 1) { const entities = levelEntities.get(level) || new Set(); entities.forEach(entity => { const { parent } = entity; let allChecked = true; (parent.children || []).forEach(({ value }) => { const checked = checkedKeys.has(value); if (allChecked && !checked) { allChecked = false; } }); if (!allChecked) { checkedKeys.delete(parent.value); } visitedKeys.add(parent.value); }); } return Array.from(checkedKeys); } /** check时父子组件的关联 */ export function conductCheck(keyList, keyEntities, checked) { // 没有树数据则放回空 if (!keyList) { return []; } const keys = keyList.filter(key => { return !!keyEntities[key]; }); const levelEntities = new Map(); let maxLevel = 0; //将需要操作的节点根据级别分类 Object.keys(keyEntities).forEach(key => { const entity = keyEntities[key]; const { level } = entity; let levelSet = levelEntities.get(level); if (!levelSet) { levelSet = new Set(); levelEntities.set(level, levelSet); } levelSet.add(entity); //获取最深的级别 maxLevel = Math.max(maxLevel, level); }); if (checked) { let result; if (checked === true) { result = fillConductCheck(new Set(keys), levelEntities, maxLevel); } else { result = cleanConductCheck(new Set(keys), levelEntities, maxLevel); } return result; } return []; }