X6
X6 copied to clipboard
Addon 拖拽支持异步获取节点
功能描述
getDragNode getDropNode 支持异步函数
getDropNode: async (draggingNode: Node, options: Addon.Dnd.GetDropNodeOptions) => {
const dropNode = await onNodeDrop(draggingNode, graph, extraOptions);
return dropNode ? dropNode : draggingNode.clone();
}
期望解决方案
getDropNode: async (draggingNode: Node, options: Addon.Dnd.GetDropNodeOptions) => {
const dropNode = await onNodeDrop(draggingNode, graph, extraOptions);
return dropNode ? dropNode : draggingNode.clone();
}
这个是什么场景下呀 能否详细描述下 如果是验证添加节点的话,可以用validateNode 方法来验证节点是否可以被添加
场景:添加放置的节点,是根据接口数据,动态配置的。 现状:validateNode只能判断是否被添加,无法直接动态替换放置节点,后面全量覆盖添加节点会导致添加非常卡。
添加放置的节点,是根据接口数据,动态配置的。
还不太理解这个场景,有更具体的视觉稿之类的吗?
添加放置的节点,是根据接口数据,动态配置的。
还不太理解这个场景,有更具体的视觉稿之类的吗?
这个跟视觉稿没关系啊,就是支持一下异步函数,让用户可以使用异步节点。我来提个PR吧。
@gavinwyf 如果是异步获取的话,那刚开始展示的图形从哪里来呢?
这里是希望拖拽过程中或者拖拽结束后异步地配置 Node 信息吗
如果只是希望对最终添加到图上的节点进行异步配置,在暂时不支持 async 的情况下,可以考虑
- 通过 getDropNode 同步地生成一个暂时性的节点,然后通过事件
node:added
在事件函数里进行异步操作?或者 - (比较不优雅的,带副作用的方法)
validateNode
支持返回Promise
, 那么在validateNode
中直接对droppingNode
进行修改?
是的,拖拽后的自定义节点内的数据全部是动态生成异步返回的。 我现在就是在validateNode里面操作的,先临时解决一下,后面有空再优化。
场景:添加放置的节点,是根据接口数据,动态配置的。 现状:validateNode只能判断是否被添加,无法直接动态替换放置节点,后面全量覆盖添加节点会导致添加非常卡。
这里为什么说后面会全量覆盖添加节点导致卡?
这里如果是请求接口动态生成节点,那么,正确的逻辑应该是让validateNode永远返回false,x6会自动删除那个droppingNode。 自己在这个函数里面添加一个新的节点就好了,这个操作理论上应该不会导致全量更新节点之类的。
这里如果是请求接口动态生成节点,那么,正确的逻辑应该是让validateNode永远返回false,x6会自动删除那个droppingNode。
但是如果是仅仅设置成 false 的话,在交互上给使用者呈现的视觉效果会变成 drag and drop 没有成功,尤其是异步过程用时较长的话,看起来就是“好像没拖拽成功,但是其实最后成功了”(基本上 >200ms 即会有明显的感知)
其实从 UX 视角来看,拖拽事件和其他鼠标事件一样,属于需要迅速完成反应的事件;在这里对于框架一个很现实的问题是:如果 getDropNode
允许异步运行,那么从 pending
到 resolve
这一段长度我们不可预知的时间内,图处于一个什么状态?我们可以显示什么?我们怎么样向使用者传递“正在添加节点”的信息?
现在这些考量是交给开发者,比如开发者可以先生成一个临时的 node, 再通过事件异步过程完成后,再更新这个临时的节点;或者像官网文档的示例那样,在 validateNode
里给 droppingNode
添加一个 spinner, 并且在异步结束后取消这个 spinner
之后如果我们的确在 getDroppingNode
支持 async, 或许我们可以暂时将 dropping node 维持在画布上,并且添加一个默认的 spinner
@tonywu6 抱歉我前面描述有问题。
validateNode永远返回false 我其实想要描述的是 validateNode永远返回一个resolve fase的Promise
validateNode(node, options) {
return new Promise((resolve, reject) => {
// 请求后端动态生成节点
return request('/api/xxxx').then((res) => {
// 这里可以处理添加节点逻辑
}).finally(() => {
resolve(false)
})
})
}
可能开发者陷入了一个误区,认为getDropNode放到画布上面的就是最终的节点了。后续的逻辑还是围绕这个节点展开。
其实现在x6这个dnd的逻辑设计得已经挺完善的了,在getDropNode直接先放一个临时节点到画布,才是一个正确的逻辑。
在validateNode这个函数支持异步,用户可以在异步逻辑执行完之后再去决定是否使用这个getDropNode返回的节点,还是放弃这个临时节点,自己创建新的节点。
This thread has been automatically locked because it has not had recent activity.
Please open a new issue for related bugs and link to relevant comments in this thread.