React+TS环境下Autodesk Forge Viewer AggregatedView初始化失败求助
解决Autodesk Forge AggregatedView初始化时的
Cannot read properties of null错误 问题背景
尝试通过React组件使用AggregatedView初始化Forge Viewer并加载多模型时,在await view.init(refElement, options3d)处触发错误:Cannot read properties of null (reading 'getBoundingClientRect')。
错误原因
- 传递给初始化函数的是React useRef对象本身,而非实际DOM元素(
ref.current),导致view.init无法获取有效的渲染节点 - 未在初始化前校验DOM元素是否已完成挂载,组件挂载阶段
ref.current为null,直接调用初始化会引发空指针异常
解决方案
1. 修改React组件的useEffect逻辑
确保传递DOM元素而非ref对象,增加DOM存在校验,并添加清理函数避免内存泄漏:
import { initializeViewer } from "./Aggregated-helper" import { useEffect, useRef } from 'react' declare var Autodesk: any export interface ForgeViewerProps { urn: string accessToken: string } const models = [ { urn: 'urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLktmSE5VSkFSUklxdE53RnZUM2o2MUE_dmVyc2lvbj0x' }, { urn: 'urn:dXJuOmFkc2sud2lwcHJvZDpmcy5maWxlOnZmLllhbk0wUHZxVGFLVnJJbnJKSG9OaFE_dmVyc2lvbj0z' } ]; const AggregatedViewer = (props: ForgeViewerProps) => { const { accessToken } = props const viewer3DRef = useRef<HTMLDivElement>(null) useEffect(() => { if (!accessToken || !viewer3DRef.current || !Autodesk) { console.log("缺少必要参数或DOM未挂载") return } initializeViewer(viewer3DRef.current, models, accessToken) // 组件卸载时清理Viewer实例,避免内存泄漏 return () => { if (window.viewer) { window.viewer.finish() window.viewer = null } } }, [accessToken]) return( <> <div ref={viewer3DRef} className="ForgeViewer" style={{ height: "100vh", width: "100%" }} ></div> </> ) } export default AggregatedViewer
2. 修改辅助函数的初始化逻辑
添加DOM元素有效性校验,增加错误捕获,并优化模型加载流程:
declare var Autodesk: any export const initializeViewer = async (refElement: HTMLElement, models: Array<{ urn: string }>, accessToken: string) => { // 先校验DOM元素是否有效 if (!refElement) { console.error("无法获取有效的DOM元素用于初始化Viewer") return } const options = { env: "AutodeskProduction", accessToken: accessToken, api:'derivativeV2' } const options3d = { viewerConfig: { disableBimWalkInfoIcon: true } }; Autodesk.Viewing.Initializer(options, async function () { const view = new Autodesk.Viewing.AggregatedView(); try { // 初始化AggregatedView await view.init(refElement, options3d) // 将viewer实例挂载到window方便调试和清理 window.viewer = view.viewer // 批量加载模型文档 const tasks = models.map(md => loadManifest(md.urn)) const docs = await Promise.all(tasks) // 提取有效的3D几何节点 const validBubbles = docs.flatMap(doc => { const bubbles = doc.getRoot().search({ type: 'geometry', role: '3d' }); return bubbles.length > 0 ? [bubbles[0]] : [] }) if (validBubbles.length > 0) { await view.setNodes(validBubbles) } else { console.error("没有找到可加载的3D模型节点") } } catch (err) { console.error("初始化AggregatedView或加载模型失败", err) } }) function loadManifest(documentId: string) { return new Promise<any>((resolve, reject) => { const onDocumentLoadSuccess = (doc: any) => { // 下载AEC模型数据(针对建筑类模型) doc.downloadAecModelData(() => resolve(doc)); }; const onDocumentLoadFailure = (err: any) => { console.error(`加载文档${documentId}失败`, err) reject(err) } Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure); }) } }
3. 额外注意事项
- 确保已在页面中正确加载Forge Viewer的脚本和样式,例如在
public/index.html中添加:<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css"> <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script> - 确保
accessToken拥有读取指定模型URN的权限 - 避免重复初始化Viewer,通过
accessToken作为useEffect的依赖项,确保仅当token变化时重新初始化
内容的提问来源于stack exchange,提问作者Manriss
相关产品推荐
相关产品推荐

