zTree / zTree_v3

jQuery Tree Plugin
MIT License
4.1k stars 1.28k forks source link

是否支持自定义异步加载方法? #463

Closed imyuyu closed 4 years ago

imyuyu commented 4 years ago

现在插件自带的async配置很全,也比较强大。但是由于我们框架一些因素,我需要自己来定义async的行为;

目前我的实现方式如下

  1. 配置假的async

    async = {
    enable:true,
    url:"/made-up/"
    }
  2. 通过beforeAsync阻止默认的ajax行为,并执行自定义的ajax行为:

beforeAsync:function(treeId,treeNode,){ // 执行自定义的ajax动作 fetch("xxxService",function(nodes){ // 调用api进行追加数据 zTreeObj.addNodes(treeNode,nodes); }) // 阻止默认行为 return false; }


经过测试确实能够实现我的需求,但是感觉不够规范,这样做了后,很多事件无法触发,如```onAsyncError```、```onAsyncSuccess ```,请问大佬有没有更优雅的办法?或者可以让我手动触发```onAsyncError```?

--- -------------------------------续,以下内容和上面没啥关系-------------------------------

是否支持渲染节点名称?比如设置```setting.data.key.name="name"```,我想拿到node.name后重新渲染一下再展示,目前我的实现逻辑是:

// 设置为nameDisplay setting.data.key.name="nameDisplay"

// 使用dataFilter或onAsyncSuccess,给节点增加 nameDisplay

zTree commented 4 years ago

你好,

利用 beforeAsync return false; 阻止 zTree 默认的 异步加载功能完全没有问题,只不过这时候就尽量别再考虑 zTree 的 onAsyncSuccess 和 onAsyncError 了。 因为 zTree 在触发 success 的时候,已经进行完毕 添加节点的工作了,你只是单纯触发 Succss 感觉意义不大,毕竟 添加节点和过滤节点的操作你还要自己来完成的。

你完全可以参考 zTree 在 core 里面的 $.ajax 的逻辑去封装一下自己的异步加载逻辑,只要你正常封装,那就没有什么不优雅的,而且你都已经不使用 zTree 的异步加载,那么也完全可以自己定义一套 success 和 error 的 callback了。

备注,硬要触发 onAsyncError 和 onAsyncSuccess 也没什么不可以,同样是看 $.ajax 部分的代码,模仿其 触发 事件的方式以及参数就可以了。


另一个问题, 关于 渲染名称,目前的代码不支持显示时利用配置的 function 动态生成节点名称,最好的方式就是,生成满意的数据格式,或者在异步加载后,添加节点之前先把数据重新处理一遍。 也就是你目前的操作方式,我觉得是可行的。就是 在编辑节点时,别忘了 name 和 nameDisplay 都要处理一下

imyuyu commented 4 years ago

感谢大佬的回复,我现在做了以下两个动作:

  1. 替换原生的$.fn.zTree._z.view.asyncNode为我司自定义的方法,
  2. 替换原生的$.fn.zTree._z.data.nodeName,$.fn.zTree._z.data.nodeTitle,并增加render()函数

$.extend($.fn.zTree._z,{ view:{ asyncNode:function(){ // 修改 $.ajax部分 } }, data:{ nodeName:function (setting, node, newName) { var key = setting.data.key.name; if (typeof newName !== 'undefined') { node[key] = newName; } // 此处着手增加render函数 var rawName = "" + node[key]; if($.isFunction(setting.data.render.name)){ return setting.data.render.name.call(this,rawName,node); } return rawName; }, nodeTitle:function(){ // 类似nodeName的操作 } } })


这样修改后,setting增加了几项属性:

setting:{ data:{ render:{ name:function(rawValue,node){} title:function(rawValue,node){} } } }



-----

其实最开始针对```asyncNode```我是准备直接将async赋值为一个函数,然后判断其是否是一个函数,后来发现调用 ```setting.async.enable```的地方太多了,就不想改了哈哈。
imyuyu commented 4 years ago

大佬,我针对节点渲染发起了一个合并请求 #464,把我之前采用扩展实现的在源码里面调整了一下。

zTree commented 4 years ago

@i 感谢你对 zTree 的支持,近期本人太忙,等过了这一阵子,我去合并你的代码。

zTree commented 3 years ago

@imyuyu 十分抱歉,昨天终于合并过来了,哈哈

imyuyu commented 3 years ago

@imyuyu 十分抱歉,昨天终于合并过来了,哈哈

说明大佬一天业务繁忙,居然还有时间搞开源,太强了。哈哈

zTree commented 3 years ago

@imyuyu 十分抱歉,昨天终于合并过来了,哈哈

说明大佬一天业务繁忙,居然还有时间搞开源,太强了。哈哈

一个字:“懒”

imyuyu commented 2 years ago

建议将async配置增加一个可以自定义的请求函数,比如

const setting = {
  async: {
    customRequestFunc: (treeId, treeNode, callback) => {
      axios.get('/xxx/', { parentId: treeNode.orgId }, (res) => {
        const childsNodes = res.data ?? []
        callback(childsNodes)
      })
    }
  }
}

我开始是准备这样,后来发现改动比较多,而且现在这种方式也能满足,就没有加函数了。

zTree commented 2 years ago

建议将async配置增加一个可以自定义的请求函数,比如

const setting = {
  async: {
    customRequestFunc: (treeId, treeNode, callback) => {
      axios.get('/xxx/', { parentId: treeNode.orgId }, (res) => {
        const childsNodes = res.data ?? []
        callback(childsNodes)
      })
    }
  }
}

我开始是准备这样,后来发现改动比较多,而且现在这种方式也能满足,就没有加函数了。

这样做的好处是,不会破坏ztree的内部逻辑,callback回传给ztree后,所有事件仍然按照原来的方式走。 而且我感觉其实async配置本来就应该设计成这样,灵活许多。

你说的很对,不过十年前貌似真没考虑到这些,而且当时也没有 async 和 await;目前已经不打算做这种改动了,毕竟用 zTree 的人也越来越少了,这东西也该逐渐退出江湖啦。如果你那边需要的话,可以自行修改源码。

zTree commented 2 years ago

你这是在刺激我用 typescript 完全重写一次了。。。。我考虑考虑啥时候会有这种冲动 。。。非常感谢你对 zTree 的信任和支持啊!