tree结构中根据Id获取父节点信息

问题1:拖拽排序

背景:前几天做了这样一个需求 – 类目(组件选用的el-tree)支持拖拽排序
在这里插入图片描述
其实el-tree本就可以实现拖拽,只需要添加一个draggable树形就可以了,拖拽完成后全量更新数据即可。

但是全量更新数据的性能开销比较大(主要开销在于后端),所以当时技术方案定的是:

  • 如果移动到一个空的目录,preCategoryId = null && nextCategoryId = null
  • 如果移动到一个非空目录到最上方,preCategoryId = null
  • 如果移动到一个非空目录到最下饭,nextCategoryId = null
  • 否则传对应preCategoryId,nextCategoryId

在这个过程中,难点就是去获取preCategoryId、nextCategoryId,即要获取父节点的数据:

获取参数实现:

 // 获取参数
 // data:父节点数据
 // draggingNode 当前拖拽节点
  const getParams = (data: TreeItem, draggingNode: { data: { categoryId: string } }) => {
    let preCategoryId: string | undefined = "";
    let nextCategoryId: string | undefined = "";
    let parentCategoryId: string | undefined = "";

    parentCategoryId = data.categoryId;
    const index = data.children!.findIndex((i) => i.categoryId === draggingNode.data.categoryId);
    if (data.children!.length === 1) {
      // 如果移动到一个空的目录,preCategoryId = null && nextCategoryId = null 都为空
      preCategoryId = undefined;
      nextCategoryId = undefined;
    } else if (!index) {
      // 如果移动到一个非空目录到最上方,preCategoryId = null
      preCategoryId = undefined;
      nextCategoryId = data.children![index + 1].categoryId;
    } else if (index === data.children!.length - 1) {
      // 如果移动到一个非空目录到最下饭,nextCategoryId = null
      preCategoryId = data.children![index - 1].categoryId;
      nextCategoryId = undefined;
    } else {
      preCategoryId = data.children![index - 1].categoryId;
      nextCategoryId = data.children![index + 1].categoryId;
    }
    return {
      preCategoryId,
      nextCategoryId,
      parentCategoryId,
    };
  };
  // 根据id获取父节点数据
  const getparentDataById = (id: string, tree: Array<TreeItem>): TreeItem => {
    let res = null;
    for (let i = 0; i < tree.length; i++) {
      let ele = tree[i];
      ele.categoryId === id ? (res = ele) : "";
      if (res) break;
      if (ele.children!.length) {
        res = getparentDataById(id, ele.children!);
      }
    }
    return res!;
  };

问题2: 展开类目

一个需求是:加载页面后,展开当前选中的意图所在的类目,效果:
在这里插入图片描述
el-tree组件提供的属性: :default-expanded-keys="expandedKeys", 实现的关键就是根据当前类目的id查询他所有的祖父元素的id(expandedKeys),绑定到属性default-expanded-keys上就可以了.

// eltree根据id获取所有父节点的id,
function getParentIds(treeData: Array<TreeItem>, id: string) {
  let str = "";
  const joinStr = ",";

  for (var i = 0, len = treeData.length; i < len; i++) {
    var item = treeData[i];
    if (item.categoryId === id) {
      return item.categoryId;
    }
    if (item.children) {
      str = item.categoryId + joinStr + getParentIds(item.children, id);
      if (str === item.categoryId + joinStr) {
        str = "";
      } else {
        return str;
      }
    }
  }
  return str;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在js,树形结构数据最常见的形式是一个嵌套数组,其每个元素都代表一个节点,包含了节点的属性和子节点数组。如果我们要根据当前节点id获取其所有的父节点id,需要进行递归操作。 首先,我们需要寻找当前节点在树形结构的位置,可以通过遍历整个数组来寻找。如果找到了当前节点,就可以继续递归查找其父节点,直到根节点。 递归查找父节点的方法可以通过传入参数来实现。在每个递归函数,我们都可以将当前节点父节点id作为参数传入,并将其插入到结果数组,然后继续递归查找父节点父节点,直到根节点为止。 具体实现的伪代码如下: ``` function findParents(treeData, nodeId, result, parentId) { for (var i = 0; i < treeData.length; i++) { var node = treeData[i]; if (node.id === nodeId) { result.unshift(parentId); if (parentId) { findParents(treeData, parentId, result, node.parentId); } break; } else if (node.children && node.children.length > 0) { findParents(node.children, nodeId, result, node.id); } } } ``` 在这个递归函数,第一个参数是整个树形数据,第二个参数是当前节点id,第三个参数是保存父节点id的结果数组,第四个参数是当前节点父节点id。当找到当前节点时,将其父节点id插入到结果数组,并继续递归查找其父节点,直到根节点为止。 通过这个递归函数,我们就可以根据树形数据和当前节点id获取其所有的父节点id了。 ### 回答2: JS树形结构是一个常见的数据结构,其每个节点都可以有其若干个子节点,而每个子节点也可以有其下属子节点,从而形成一棵具有階次关系的树形结构。 当我们需要根据某个节点获取父节点ID时,我们可以使用递归来实现。具体步骤如下: - 首先,我们需要获取与给定ID相关联的节点数据。如果树形数据存储在数组,则我们可以通过循环遍历整个数组来找到该节点。 - 接下来,我们需要判断当前节点是否为根节点,如果是则返回null,因为根节点没有父节点。 - 如果当前节点不是根节点,则我们需要继续递归地向上查找其祖先节点,直到找到根节点。为此,我们可以调用函数本身,并将当前节点父节点ID作为参数传递到函数。 - 如果我们找到根节点,则可以停止递归,并将其父节点ID返回。如果找不到根节点,则说明给定的ID是不合法的,可以返回null或抛出异常。 下面是一个示例代码,它使用递归来获取指定节点的祖先节点: function getParentNodeId(treeData, nodeId) { // 查找指定ID节点的数据 for (let i = 0; i < treeData.length; i++) { if (treeData[i].id == nodeId) { // 如果当前节点是根节点,则返回null if (!treeData[i].parentId) { return null; } // 否则递归查找父节点ID return getParentNodeId(treeData, treeData[i].parentId); } } // 如果找不到指定ID节点,则返回null return null; } 在实际应用,我们可以根据具体需求对该函数进行扩展,例如增加是否返回完整的父节点数据等功能。 ### 回答3: 在js树形结构,我们通常需要根据树形数据和当前id来递归获取父节点id。实现该功能的基本思路是:首先根据当前id查找包含该id节点,然后递归查找该节点父节点直到根节点,最后返回根节点id。 具体实现过程如下: 1. 定义一个函数,命名为getTreeParentId,该函数有两个参数:treeData和currentId。其treeData是整棵树的数据,currentId是需要查找的节点id。 2. 在函数定义一个变量,命名为parentId,并将其初始化为null。 3. 遍历整个树形数据,查找包含currentId节点。 4. 如果找到了该节点,就把该节点父节点id赋值给parentId,并结束遍历。 5. 如果没有找到该节点,则递归遍历当前节点的子节点,直到找到为止。 6. 最后返回parentId,即为该节点父节点id。 下面是一个实现示例: ``` function getTreeParentId(treeData, currentId) { var parentId = null; for (var i = 0; i < treeData.length; i++) { var node = treeData[i]; if (node.id === currentId) { parentId = node.parentId; break; } if (node.children && node.children.length > 0) { parentId = getTreeParentId(node.children, currentId); if (parentId) { break; } } } return parentId; } ``` 上述代码实现了根据树形数据和当前id递归获取父节点id的功能。使用时,只需调用该函数并传入treeData和currentId参数即可。 需要注意的是,上述代码假定树形数据的每个节点都有一个唯一的id,并且每个节点的parentId为null或者他的父节点id。如果树形数据的结构不同,需要进行相应的修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值