多模型场景下如何获取各模型RootID?Forge Viewer API
多模型场景下属性遍历解决方案
问题核心
你的代码始终只处理第一个加载模型的原因有两个:
- 递归函数硬依赖
viewer.model,而该属性默认指向第一个加载的模型 viewer.getProperties未指定目标模型,默认仅查询第一个模型的属性- 递归调用未等待异步操作完成,导致遍历流程提前结束
代码修改方案
1. 重构递归函数(支持指定模型实例)
修改递归逻辑,让它接收当前模型实例作为参数,所有操作都基于该模型:
async function extractAttributesRecursively(dbId, filterValue, modelInstance, depth = 0) { return new Promise(async (resolve) => { // 关键:指定当前模型获取属性 viewer.getProperties(dbId, function(properties) { if (properties) { const levelAttribute = properties.properties.find(prop => prop.displayName === filterValue); if (levelAttribute) { if (!valueMatrix[filterValue]) { valueMatrix[filterValue] = []; } // 去重处理,避免重复属性值 if (!valueMatrix[filterValue].includes(levelAttribute.displayValue)) { valueMatrix[filterValue].push(levelAttribute.displayValue); } } else if (depth < MAX_RECURSION_DEPTH) { // 使用当前模型的实例树遍历子节点 modelInstance.getInstanceTree().enumNodeChildren(dbId, async function(childId) { // 等待递归完成,保证遍历顺序 await extractAttributesRecursively(childId, filterValue, modelInstance, depth + 1); }); } } resolve(); }, { model: modelInstance }); // 传递模型参数,指定查询目标 }); }
2. 修正模型遍历逻辑
调整遍历函数,将当前模型实例传递给递归函数,并修正对象遍历方式:
async function getTreefromObject() { var modelInstance; var objectTree; var rootId; // 若loadedModels是键值对对象,用Object.keys遍历URN for (var urn of Object.keys(loadedModels)) { modelInstance = loadedModels[urn]; console.log('当前处理模型:', urn); objectTree = await new Promise((resolve) => { modelInstance.getObjectTree(function(objectTree) { resolve(objectTree); }); }); rootId = objectTree.getRootId(); console.log('模型RootID:', rootId); for (var filterValue of FILTER_VALUES) { console.log('当前搜索属性:', filterValue); // 传递当前模型实例给递归函数 await extractAttributesRecursively(rootId, filterValue, modelInstance); } } }
关键说明
- 模型实例绑定:所有属性查询、节点遍历操作都必须基于当前遍历的
modelInstance,而非viewer.model - 异步等待:递归调用时添加
await,确保子节点遍历完成后再继续父节点流程 - 值去重:添加
includes判断避免重复属性值,生成更干净的过滤列表 - 遍历正确性:如果
loadedModels是键值对结构,必须用Object.keys()遍历URN,否则会遍历到对象原型属性
内容的提问来源于stack exchange,提问作者Luksa
相关产品推荐
相关产品推荐

