BasicTree懒加载模式下,节点增删改后动态刷新

BasicTree懒加载模式下,节点增删改后动态刷新

jeecgboot在antv树控件基础删封装了BasicTree,懒加载模式下,节点增删改后动态刷新

起源

使用jeecgboot开发一个左树右表的页面,树和列表都需要增删改的功能,树采用懒加载模式,在生成的代码基础上改造。

先说问题

  • 问题一(直接问题):树节点增、删、改后,怎样动态刷新
  • 问题二(间接问题,要填坑):展开节点时出现浏览器卡死、无响应的情况

问题一解题

解题思路和过程

编辑(含删除、添加,下文统称编辑)节点后,重新加载当前节点所在的层级,并展开一展开的节点

在编辑成功的success回调里,调用updateNodeByKey方法可更新节点数据:

tree.updateNodeByKey(key, { children: records });

调用后编辑的节点更新了,但是这个节点的子节点(如果有子节点,并且是展开过的)没了,变成了leaf状态
在这里插入图片描述

原因:antv判断是否有子节点用的isLeaf属性,而jeecgboot封装的basicTree用的是hasChild属性。不知道是封装没处理好还是我哪里没写对,通过编辑回调的时候就会变leaf,但是展开的时候又正常

解决方法:在编辑回调的时候手动给数据增加isLeaf属性

let records = res.records;
for (let i = 0; i < records.length; i++) {
  if (records[i].hasChild == '1') records[i].isLeaf = false;
}

这时候可以正常判断leaf了。但节点下的数据没了
在这里插入图片描述

  • antv使用expandedKeys保存已展开的节点
  • loadedKeys保存已“展开过”的节点

节点展开过,antv在loadedKeys保存了这些key,再次展开会从缓存数据读取。但更新过节点数据,缓存里没有children,所以出现这种情况。
处理方法就是重新加载的时候在loadedKeys里删除涉及的key

(部分关键代码)

//BasicTree的属性绑定loadedKeys
<BasicTree
    ...
    :loadedKeys="loadedKeys"
    ///
/>

//定义loadedKeys变量
let loadedKeys = ref<any[]>([]);

//加载的时候删除key
loadedKeys.value.splice(0, 1, parId);

至此,理论上应该解决问题了。但是出现了新问题,也就是前面提到的“问题二”

问题二,展开节点时出现浏览器卡死、无响应的情况

现象:展开节点,页面卡死,无响应。如果在展开节点事件的方法打了console.log,可以看到控制台在疯狂输出。

解决:应该是展开时没有更新loadedKeys,导致antv认为还没展开。所以把展开的key加入到loadedKeys即可:

loadedKeys.value = uniq([...loadedKeys.value, parId]);

最后贴上代码

加载树节点代码(这里要返回Promise对象)

  function loadChildDataByTreeNode(treeNode) {
    return new Promise((resolve) => {
      if (treeNode.dataRef.children) {
        resolve(true);
        return;
      }
      let parId = treeNode.dataRef.id;
      let param = {
        parId: treeNode.dataRef.id,
      };
      loading.value = true;
      getChildList(param)
        .then((res) => {
          if (!Array.isArray(res.records) || res.records.length == 0) {
            loadedKeys.value = uniq([...loadedKeys.value, parId]);
            resolve(true);
            return false;
          }
          let records = res.records;
          for (let i = 0; i < records.length; i++) {
            if (records[i].hasChild == '1') records[i].isLeaf = false;
          }
          let tree = getTree();
          tree.updateNodeByKey(treeNode.eventKey, { children: records });
          tree.setExpandedKeys(uniq([treeNode.eventKey, ...tree.getExpandedKeys()]));
          resolve(true);
        })
        .finally(() => (loading.value = false));
    });
  }

编辑后动态刷新代码

  async function loadChildDataByParId(parId) {
    loading.value = true;
    let param = {
      parId: parId,
    };
    const res = await getChildList(param);
    if (!Array.isArray(res.records)) {
      return;
    }
    let records = res.records;
    for (let i = 0; i < records.length; i++) {
      if (records[i].hasChild == '1') records[i].isLeaf = false;
    }
    let tree = getTree();
    //处理loadedKeys
    loadedKeys.value.splice(0, 1, parId);
    tree.updateNodeByKey(parId, { children: records });
    tree.setExpandedKeys(uniq([parId, ...tree.getExpandedKeys()]));
    loading.value = false;
  }

补充代码getTree()

const asyncTreeRef = ref<Nullable<TreeActionType>>(null);
function getTree() {
const tree = unref(asyncTreeRef);
if (!tree) {
  throw new Error('tree is null!');
}
return tree;
}
<BasicTree
    <!--其他部分省略-->
    ref="asyncTreeRef"
/>

最后

大家如果有其他思路,欢迎交流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值