【js】根据一个id去递归寻找这个id的所有上级id,把他们放进一个数组

功能:用于在树形结构中查找包含指定关键字的节点,并将这些节点的id以及其所有上级节点的id存储在expandedKeys中,以实现a-tree的搜索后自动展开满足搜索条件的树节点

const expandedKeys = ref<string[] | number[]>([])
cosnt searchValue = ref<string>('')

treeList是当前搜索后返回的树形结构的数据,keyword是搜索的关键字,expandedKeys是存储展开节点id的数组,parentIds是存储当前节点的所有上级节点id的数组,默认给个空数组

const findNodesToExpand = (
	treeList: Array<any>, 
	keyword: string, 
	expandedKeys: string[], 
	parentIds: string[] = []
) => {
    
    
  // 1、一开始treeList肯定是搜索后的全部数据,forEach遍历第一层,看factorName字段是否包含关键字keyword,如果包含,就说明这条数据就是搜索的目前数据,把他的id放入expandedKeys里面,这样这一级数据就可以自动展开了
  treeList?.forEach((node: any) => {
    
    
    if (node.factorName?.includes(keyword)) {
    
    
      expandedKeys.push(...parentIds, node.id)
    }
    // 2、判断第一层数据有没有children嵌套,有的话就遍历这个children,然后看factorName字段是否包含关键字keyword,后面实际上跟第1步一样的操作,只是每次遍历的数组不一样,此时就可以用个递归函数,递归了之后,就会开始从treeList?.forEach执行,实际上每次传入findNodesToExpand的treeList在他当下都是全部数据,都有第一层,依次类推
    // 3、主要要解释一下[...parentIds, node.id]这一步,第一遍的时候,parentIds为[],node.id有值以后,实际上[...parentIds, node.id]里面只有第一个满足条件的node.id一个值,但是在下面递归以后,下面的[...parentIds, node.id]就等同于上面的...parentIds,然后每次往里面再push满足条件的node.id,就实现了[...parentIds, node.id],即等同于parentIds,里面存储着所有满足条件的id及其所有上级id
    if (node.children?.length > 0) {
    
    
      findNodesToExpand(node.children, keyword, expandedKeys, [...parentIds, node.id])
    }
  })
}

这段可能有些抽象,先是定义了一个空数组expandedKeys,然后调用了findNodesToExpand函数,把这个空数组expandedKeys作为实参传给了findNodesToExpand内部,findNodesToExpand内部给这个空数组expandedKeys赋了值,再在optimizeExpandedKeys 里面return定义的expandedKeys,就可以通过调用optimizeExpandedKeys 这个函数拿到当前目标id及其所有上级id的数组集合。

注意:有一个点,就是findNodesToExpand函数内部并没有return expandedKeys,那是为何调用findNodesToExpand就可以得到存储着目标id及其所有上级id的数组集合呢?那是因为expandedKeys是引用数据类型,当在函数内部修改expandedKeys数组时,实际上实在原始的expandedKeys数组上进行修改,也就是optimizeExpandedKeys 内部定义的expandedKeys上进行修改,而不是创建一个新的数组,所以无需return或赋值

const optimizeExpandedKeys = (
	treeList: Array<any>, 
	keyword: string
) => {
    
     
  const expandedKeys: string[] = [] 
  findNodesToExpand(treeList, keyword, expandedKeys) 
  return expandedKeys 
}

调用

// 给expandedKeys赋值前要先判断一下是否有搜索词,如果没有的话,要给expandedKeys.value设置为[],不然所有节点都会被默认展开
expandedKeys.value = searchValue .value ? optimizeExpandedKeys(treeData, leftKeyWord.value) : []

猜你喜欢

转载自blog.csdn.net/bbt953/article/details/132631794
今日推荐