You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对象数组循环遍历问题及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;
}

问题分析

  1. 循环内重复过滤数组:每次循环都重新执行过滤操作,造成冗余计算,且过滤后的数组selectedScenceFiltered和原数组foundAllSelected索引不匹配,导致判断状态时取错节点。
  2. 重复执行批量操作:循环遍历原数组时,每一次循环都会触发一次批量选择/取消,多次操作相互覆盖,导致UI状态混乱。
  3. 变量作用域问题:使用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);
    }
}

修正说明

  1. 提前统一过滤:先判断是否存在contact类型节点,再一次性完成过滤,避免循环内重复计算,保证过滤逻辑一致性。
  2. 单次批量操作:仅根据过滤后数组中第一个节点的状态,执行一次批量选择或取消操作,避免重复操作导致的状态冲突。
  3. 边界条件处理:增加空数组判断,避免无节点时执行无效操作;增加节点存在性判断,防止sceneNodeMap中找不到对应节点的情况。
  4. 变量优化:使用const声明常量,避免变量作用域问题。

内容的提问来源于stack exchange,提问作者GeekAndNerd223

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:30:54