UNPKG

zarm-web

Version:
421 lines (336 loc) 12.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.deepCopy = deepCopy; exports.arrDel = arrDel; exports.arrAdd = arrAdd; exports.convertTreeToData = convertTreeToData; exports.isCheckDisabled = isCheckDisabled; exports.conductCheck = conductCheck; exports.conductExpandParent = conductExpandParent; exports.initialTreeData = initialTreeData; exports.getTreeNodeChildren = void 0; var _react = _interopRequireDefault(require("react")); var _TreeNode = _interopRequireDefault(require("./TreeNode")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } // 判断当前对象是否是object类型 function isPlainObject(obj) { if (Object.prototype.toString.call(obj).toLowerCase() !== '[object object]') { return false; } var proto = Object.getPrototypeOf(obj); if (!proto) { return true; } return proto.constructor && proto.constructor === Object; } // 深拷贝对象 function deepCopy(data) { if (Array.isArray(data)) { return data.map(function (elem) { return deepCopy(elem); }); } if (!isPlainObject(data)) { return data; } return Object.keys(data).reduce(function (prev, key) { var value = data[key]; prev[key] = deepCopy(value); return prev; }, {}); } /** * 对数组删除一个指定的值 * @param list {Array} 要处理的数组 * @param value 要删除的值 * @returns {Array} 返回的新数组 */ function arrDel(list, value) { var clone = list.slice(); var index = clone.indexOf(value); if (index >= 0) { clone.splice(index, 1); } return clone; } /** * 对数组添加一个指定的值 * @param list {Array} 要处理的数组 * @param value 要添加的值 * @returns {Array} 返回的新数组 */ function arrAdd(list, value) { var clone = list.slice(); if (clone.indexOf(value) === -1) { clone.push(value); } return clone; } /** * 对当前节点过滤出所属TreeNode类型的节点 * @param node {object} 要处理的节点对象 * @returns {Array} 返回过滤完的节点 */ var getTreeNodeChildren = function getTreeNodeChildren(node) { var children = node.children; return _react.default.Children.toArray(children).filter(function (item) { if (item && item.type === _TreeNode.default) { return true; } return false; }).map(function (item) { return item; }); }; /** * 将React的TreeNode节点全部转化为普通的树形结构的object * @param node {object} 要处理的节点对象 * @returns {Array} 返回过滤完的节点 */ exports.getTreeNodeChildren = getTreeNodeChildren; function convertTreeToData(treeNode) { if (treeNode && treeNode.length !== 0) { return _react.default.Children.toArray(treeNode).map(function (node) { var _node$props = node.props, children = _node$props.children, props = _objectWithoutProperties(_node$props, ["children"]); var obj = _objectSpread({}, props); if (children) { var treeNodeChildren = getTreeNodeChildren({ children: children }); if (treeNodeChildren.length > 0) { obj.children = convertTreeToData(treeNodeChildren); } } return obj; }); } return []; } // 判断当前节点是否是禁用状态 function isCheckDisabled(node) { var _node$checkDisabled = node.checkDisabled, checkDisabled = _node$checkDisabled === void 0 ? false : _node$checkDisabled; return checkDisabled; } /** * 根据keys来获取对应的node * @param keys {string} 要获取的结点的keys * @param treeData {array} 整个树结点 */ function getNodeFromKey(keys, treeData) { return keys.split('-').reduce(function (node, keySplit, index) { if (!node || node.length === 0) { return null; } return index === 0 ? node[keySplit] : (node.children || [])[keySplit]; }, treeData); } /** 根据当前传入结点的选中状态,更新当前结点的已选中节点的总数 * @param node {object} 当前传入结点 * @param isChecked {bool} 目标变化是否选中 * @param conductDirection {string} 当前是向上还是向下关系的更新 */ function resetNodeCheckedState(node, isChecked, conductDirection) { if (conductDirection === 'up') { isChecked ? node.checkedCount += 1 : node.checkedCount -= 1; } else { var nodeLength = (node.children || []).filter(function (child) { return !isCheckDisabled(child); }).length; isChecked ? node.checkedCount = nodeLength : node.checkedCount = 0; } } /** * 根据选中状态变化的结点的keys数组,经过父级以及子级层层遍历判断,得到最终选中结点的数组以及更新状态属性后的treeData * @param keysList {array} 状态变化的结点keys数组 * @param isChecked {boolean} 目标变化状态(是否选中) * @param treeData {array} 整个树结点数组 * @param originCheckedStateMap 原有所有选中结点的keys数组(包含全选中、未全选状态的节点数组) * @returns {checkedKeys, halfCheckedKeys, treeData} */ function conductCheck(keysList, isChecked, treeData, originCheckedStateMap) { var checkedKeys = {}; var halfCheckedKeys = {}; var finalCheckedKeysList = []; var finalHalfCheckedKeysList = []; if (originCheckedStateMap) { // 将当前已选中的node Keys同步到checkedKeys (originCheckedStateMap.checkedKeys || []).forEach(function (keys) { checkedKeys[keys] = true; }); // 将当前已选中的node Keys同步到checkedKeys (originCheckedStateMap.halfCheckedKeys || []).forEach(function (keys) { halfCheckedKeys[keys] = true; }); } function conductUp(node) { var parent = node.parent; if (!parent || isCheckDisabled(parent)) { return; } resetNodeCheckedState(parent, isChecked, 'up'); /* 以下两种情况,更新结点状态,并且递归往上继续查询且更新父结点 如果当前操作为选中,并且当前选中的个数只有一个; 如果前操作为选空,并且目前子结点已经全空。 */ if (isChecked && parent.checkedCount === 1 || !isChecked && parent.checkedCount === 0) { conductUp(parent); } } /** * 分别获取所传入节点的有效节点(未禁用),选中状态以及半选中状态的节点 * @param node 传入节点 * @returns {validNotesLen: number; checkedNotesLen: number; halfCheckedNotesLen: number} */ function getChildrenNodesLen(node) { var resObj = { validNotesLen: 0, checkedNotesLen: 0, halfCheckedNotesLen: 0 }; var validNotes = []; if (node && node.children) { validNotes = node.children.filter(function (item) { return !isCheckDisabled(item); }); resObj.validNotesLen = validNotes.length; resObj.halfCheckedNotesLen = validNotes.filter(function (item) { return halfCheckedKeys[item.keys]; }).length; resObj.checkedNotesLen = validNotes.filter(function (item) { return checkedKeys[item.keys]; }).length; } return resObj; } /** * 更新传入节点的所有父节点的选中状态 * @param node 节点 */ function setParentNodeCheckedState(node) { var parent = node.parent; if (!parent || isCheckDisabled(parent)) { return; } var _getChildrenNodesLen = getChildrenNodesLen(parent), validNotesLen = _getChildrenNodesLen.validNotesLen, checkedNotesLen = _getChildrenNodesLen.checkedNotesLen, halfCheckedNotesLen = _getChildrenNodesLen.halfCheckedNotesLen; if (checkedNotesLen === 0 && halfCheckedNotesLen === 0) { checkedKeys[parent.keys] = false; halfCheckedKeys[parent.keys] = false; } else if (validNotesLen === checkedNotesLen) { checkedKeys[parent.keys] = true; halfCheckedKeys[parent.keys] = false; } else { halfCheckedKeys[parent.keys] = true; checkedKeys[parent.keys] = false; } setParentNodeCheckedState(parent); } function conductDown(node) { if (isCheckDisabled(node)) { return; } var children = node.children, keys = node.keys; checkedKeys[keys] = isChecked; halfCheckedKeys[keys] = false; resetNodeCheckedState(node, isChecked, 'down'); if (children) { children.filter(function (child) { return !isCheckDisabled(child); }).forEach(function (_node) { conductDown(_node); }); } } (keysList || []).forEach(function (keys) { var node = getNodeFromKey(keys, treeData); if (!node) { console.warn("keys\u4E3A".concat(keys, "\u7684\u7ED3\u70B9\u4E0D\u5B58\u5728\uFF01")); return; } // 更新当前选中节点的状态 checkedKeys[keys] = isChecked; halfCheckedKeys[keys] = false; if (isCheckDisabled(node)) { return; } // 根据当前节点向上且向下更新所有父节点以及子节点的选中状态 conductUp(node); setParentNodeCheckedState(node); conductDown(node); }); Object.keys(checkedKeys).forEach(function (keys) { if (checkedKeys[keys]) { finalCheckedKeysList.push(keys); } }); Object.keys(halfCheckedKeys).forEach(function (keys) { if (halfCheckedKeys[keys]) { finalHalfCheckedKeysList.push(keys); } }); return { checkedKeys: finalCheckedKeysList, halfCheckedKeys: finalHalfCheckedKeysList, treeData: treeData }; } /** 根据传入的展开结点keys的数组,初始化最终要展开的相关所有父结点 * @param keysList {Array} 要展开的结点list数组 * @param treeData {object} 当前树形结构的map对象 */ function conductExpandParent(keysList, treeData) { var expandedKeys = {}; function conductUp(node) { if (expandedKeys[node.keys]) { return; } var parent = node.parent, keys = node.keys; expandedKeys[keys] = true; if (parent) { conductUp(parent); } } (keysList || []).forEach(function (keys) { var node = getNodeFromKey(keys, treeData); if (!node) { console.warn("keys\u4E3A".concat(keys, "\u7684\u5C55\u5F00\u7ED3\u70B9\u4E0D\u5B58\u5728\uFF01")); return; } conductUp(node); }); return Object.keys(expandedKeys); } /** 初始化treeNode树(挂载结点parent关系以及checkCount) * @param treeData {object} 当前树形结构的map对象 */ function initialTreeData(treeData) { var allExpandDataMap = {}; function loop(node, parentNode) { return node.map(function (_node) { var children = _node.children, keys = _node.keys; _node.parent = parentNode; _node.checkedCount = 0; if (children && children.length > 0) { allExpandDataMap[keys] = _node; _node.children = loop(children, _node); } return _node; }); } var finalTreeData = loop(treeData, null); return { allExpandDataMap: allExpandDataMap, treeData: finalTreeData }; }