@uiw/react-native
Version:
UIW for React Native
226 lines (213 loc) • 5.61 kB
JavaScript
/**
* 平铺树节点使节点可以进行遍历
*/
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 [];
}