对象数组循环遍历问题及ASM树选择/取消选择功能修复求助
问题:批量切换节点选中状态时重新选择无响应的修复
场景说明
我拥有一个包含asmTreeNodeFlat类型对象的数组,先获取所有selected属性为true的节点存入foundAllSelected变量,通过for循环遍历该数组,根据节点的type进行过滤(排除namedSelection类型),再依据节点在sceneNodeMap中的选中状态,执行批量选择/取消过滤后节点的操作。目前取消选择功能正常,但在UI上取消后重新选择时无响应,怀疑循环遍历方式存在问题,特附上节点类定义,请求提供修正后的代码。
原代码
public asmTreeSelectionDeselectionToggle() { const foundAllSelected = this.getAllSelectedNodes(); for (let i = 0; i < foundAllSelected.length; i++) { if (foundAllSelected[i].type !== "contact") { var selectedScenceFiltered = foundAllSelected.filter(d => ((d.type !== 'namedSelection') && (d.type !== 'contact'))); } else { var selectedScenceFiltered = foundAllSelected; } if (!!selectedScenceFiltered) { this.asmTreeShowState.isSelected(this.sceneNodeMap.get(selectedScenceFiltered[i].guid)) ? this.asmTreeShowState.select(...selectedScenceFiltered) : this.asmTreeShowState.deselect(...selectedScenceFiltered); } } }
节点类定义
export class asmTreeNodeFlat { name: string; instanceName: string; guid: string; componentId: number; url: string; transform: any = []; data: any; level: number; expandable: boolean; type: string; decimation: number = 0; showInTreeView: boolean = true; expanded: boolean = false; selected: boolean = false; }
问题分析
- 循环内重复过滤数组:每次循环都重新执行过滤操作,造成冗余计算,且过滤后的数组
selectedScenceFiltered和原数组foundAllSelected索引不匹配,导致判断状态时取错节点。 - 重复执行批量操作:循环遍历原数组时,每一次循环都会触发一次批量选择/取消,多次操作相互覆盖,导致UI状态混乱。
- 变量作用域问题:使用
var声明selectedScenceFiltered会导致变量提升,进一步加剧逻辑混乱。
修正后的代码
public asmTreeSelectionDeselectionToggle() { const foundAllSelected = this.getAllSelectedNodes(); if (foundAllSelected.length === 0) return; // 统一过滤数组:排除namedSelection类型,若存在contact类型则保留该类型节点 const hasContactType = foundAllSelected.some(node => node.type === "contact"); const selectedScenceFiltered = hasContactType ? foundAllSelected : foundAllSelected.filter(d => d.type !== 'namedSelection'); if (selectedScenceFiltered.length === 0) return; // 取第一个过滤后节点的状态作为判断依据,仅执行一次批量操作 const firstNode = this.sceneNodeMap.get(selectedScenceFiltered[0].guid); if (!firstNode) return; if (this.asmTreeShowState.isSelected(firstNode)) { this.asmTreeShowState.deselect(...selectedScenceFiltered); } else { this.asmTreeShowState.select(...selectedScenceFiltered); } }
修正说明
- 提前统一过滤:先判断是否存在
contact类型节点,再一次性完成过滤,避免循环内重复计算,保证过滤逻辑一致性。 - 单次批量操作:仅根据过滤后数组中第一个节点的状态,执行一次批量选择或取消操作,避免重复操作导致的状态冲突。
- 边界条件处理:增加空数组判断,避免无节点时执行无效操作;增加节点存在性判断,防止
sceneNodeMap中找不到对应节点的情况。 - 变量优化:使用
const声明常量,避免变量作用域问题。
内容的提问来源于stack exchange,提问作者GeekAndNerd223
相关产品推荐
相关产品推荐

