Autodesk Viewer标注工具关闭时,如何提前获取Markups数据并存库?
解决标注数据保存时机问题
你遇到的问题是全局TOOL_CHANGE_EVENT触发时机过早,导致调用generateData()时还没拿到最新的标注数据。这里给你几个靠谱的解决方案:
方案1:监听MarkupsGui面板关闭事件
放弃全局工具切换事件,直接监听标注面板的关闭动作,这个时机更准确——用户关闭面板时,标注操作已经完全结束:
// 加载模型成功后保存MarkupsGui扩展实例 let markupsGuiExt; viewer?.current?.loadModel(path.urlPath, {}, function onSuccess() { // 加载MarkupsCore viewer?.current?.loadExtension("Autodesk.Viewing.MarkupsCore"); // 加载MarkupsGui并监听面板关闭 viewer?.current?.loadExtension("Autodesk.Viewing.MarkupsGui").then(ext => { markupsGuiExt = ext; // 面板可见性变化时触发 markupsGuiExt.onPanelVisibilityChanged = (visible) => { if (!visible) { saveMarkupsToDatabase(viewer.current); } }; }); }); // 移除原有的TOOL_CHANGE_EVENT监听逻辑 // 修改保存函数,避免重复加载扩展 function saveMarkupsToDatabase(viewer: any) { // 直接获取已加载的MarkupsCore扩展 const markupsExtension = viewer.getExtension("Autodesk.Viewing.MarkupsCore"); if (!markupsExtension) return; // generateData是同步方法,不需要await const markupsData = markupsExtension.generateData(); console.log({ markupsData }); const markupsStringData = JSON.stringify(markupsData); localStorage.setItem("markups", markupsStringData); // 这里执行云数据库插入逻辑 }
方案2:使用MarkupsCore的会话完成事件
如果你的Viewer版本支持,还可以监听MarkupsCore的SESSION_COMPLETED事件,这个事件会在标注会话结束(退出标注模式)时触发:
React.useEffect(() => { const markupsCoreExt = viewer?.current?.getExtension("Autodesk.Viewing.MarkupsCore"); if (!markupsCoreExt) return; const handleSessionEnd = () => { saveMarkupsToDatabase(viewer.current); }; // 监听会话完成事件 markupsCoreExt.addEventListener(Autodesk.Viewing.MarkupsCore.EVENTS.SESSION_COMPLETED, handleSessionEnd); // 组件卸载时清理事件监听 return () => { markupsCoreExt.removeEventListener(Autodesk.Viewing.MarkupsCore.EVENTS.SESSION_COMPLETED, handleSessionEnd); }; }, [isGeometryLoaded]);
关键注意点
- 不要重复加载扩展:
loadExtension是异步操作,且如果扩展已加载,重复调用会浪费时间,直接用getExtension获取已加载的实例即可。 generateData是同步方法:不需要用await,去掉多余的异步等待能避免时序延迟问题。- 优先使用扩展自身事件:全局
TOOL_CHANGE_EVENT是通用工具切换事件,触发时机不针对标注流程,用Markups扩展专属事件能保证数据已准备好。
内容的提问来源于stack exchange,提问作者Abed Aarabi
相关产品推荐
相关产品推荐

