VisJs Timeline:拖动节点后如何实时显示更新的起止时间视图?
解决VisJS Timeline拖动节点后视图不即时更新的问题
问题根源
你直接修改了Timeline内部的itemSet.items对象数据,但VisJS的视图更新依赖于DataSet数据源的变更通知,直接操作内部渲染对象不会触发DataSet的更新事件,所以只有手动缩放/移动时间线触发强制重绘时才会显示正确位置。
修复方案
核心是通过绑定的DataSet实例(也就是你的items对象)来更新数据,而非直接操作itemSet内部对象:
- 移除对
itemSet.items的直接修改,改用items.update()方法批量更新节点数据 - 调整
onMoving中的偏移计算逻辑,确保所有节点的时间偏移正确 - 无需额外调用
redraw(),DataSet的更新会自动触发视图刷新
修改后的代码
onMoving : function (item, callback) { // 从DataSet获取当前所有节点数据,而非操作内部itemSet let allItems = items.get(); // 获取拖动前的原始节点数据(通过id匹配) let originalItem = allItems.find(i => i.id === item.id); // 计算拖动偏移量:新位置 - 原位置(修正方向逻辑) let distanceMoved = item.start.valueOf() - originalItem.start.valueOf(); // 批量计算所有节点的新时间 let updatedItems = allItems.map(node => { const newStart = new Date(node.start.valueOf() + distanceMoved); let updatedNode = { ...node, start: newStart }; if (node.end) { updatedNode.end = new Date(node.end.valueOf() + distanceMoved); } return updatedNode; }); // 通过DataSet更新数据,自动触发视图刷新 items.update(updatedItems); // 返回调整后的当前拖动节点 callback(item); } // 移除多余的update事件监听,DataSet更新会自动驱动视图刷新 // items.on('update', function (event, properties) { // viewModelCutover.timeline.timelineObject.redraw(); // });
关键说明
- 禁止操作
itemSet:itemSet是Timeline的内部渲染容器,数据来源于DataSet,直接修改此处对象无法被VisJS响应式系统捕获。 - 依赖DataSet API:
items.get()获取最新数据源,items.update()触发数据变更通知,Timeline会自动监听DataSet变化并更新视图。 - 偏移逻辑修正:原代码偏移方向存在误差,调整为
新位置 - 原位置,确保所有节点跟随拖动方向同步移动。
内容的提问来源于stack exchange,提问作者Kulu
相关产品推荐
相关产品推荐

