为什么我的angular应用程序在更改垫子树的数据后变得非常慢?

为什么我的angular应用程序在更改垫子树的数据后变得非常慢?,angular,angular-material,Angular,Angular Material,我正在实现角度/材质树组件,但遇到了一些问题。在保存对树的更改后,我正在重置支持树的数据(正常工作),但是应用程序会变得非常缓慢,扩展节点可能需要大约8秒钟 更奇怪的是,实际操作数据源的代码是在其他地方运行的,比如在树中添加新的子级-我们希望UI更新,而这不会导致问题。只有在保存时,应用程序才会变慢 save(): void { const trees = this.flattenedTree.filter(node => this.isRootNode(node));

我正在实现角度/材质树组件,但遇到了一些问题。在保存对树的更改后,我正在重置支持树的数据(正常工作),但是应用程序会变得非常缓慢,扩展节点可能需要大约8秒钟

更奇怪的是,实际操作数据源的代码是在其他地方运行的,比如在树中添加新的子级-我们希望UI更新,而这不会导致问题。只有在保存时,应用程序才会变慢

save(): void {
    const trees = this.flattenedTree.filter(node => this.isRootNode(node));

    this.serviceThatHasNoSideEffects.save(trees)
        .then(result => {
            this.tree = result;
            this.flattenedTree = this.getFlattenedTree();
            this.refreshTree();
        });
}

private refreshTree() {
    const data: any[] = this.flattenedTree
        .filter(x => this.isRootNode(x))
        .filter(x => x.children.length > 0 || x.id === this.focusId);

    this.nestedDataSource.data = null;
    this.nestedDataSource.data = data;

    const focusNode = this.getNode(this.focusId);
    this.nestedTreeControl.expand(focusNode);
}

private addChild(parentNode: any, childNode: any) {
    if (!this.getNode(parentNode)) {
        this.flattenedTree.push(parentNode);
    }

    if (!this.getNode(childNode)) {
        this.flattenedTree.push(childNode);
    }

    parentNode.children.push(childNode);

    this.refreshTree();
    this.nestedTreeControl.expand(parentNode);
}
编辑:

更改刷新树以创建一个全新的数据源可以解决速度慢的问题(内存泄漏?),但不添加子级不会显示在UI中。虽然子对象位于平坦的树上,但应显示

private refreshTree() {
    const data: any[] = this.flattenedTree
        .filter(x => this.isRootNode(x))
        .filter(x => x.children.length > 0 || x.id === this.focusId);

        this.nestedDataSource = new MatTreeNestedDataSource<theTreeType>();
    this.nestedDataSource.data = data;

    const focusNode = this.getNode(this.focusId);
    this.nestedTreeControl.expand(focusNode);
}
私有刷新树(){
常量数据:any[]=this.flattedTree
.filter(x=>this.isRootNode(x))
.filter(x=>x.children.length>0 | | x.id==this.focusId);
this.nestedDataSource=new MatTreeNestedDataSource();
this.nestedDataSource.data=数据;
const focusNode=this.getNode(this.focusId);
this.nestedTreeControl.expand(focusNode);
}
编辑:这是支持它的html。相当标准

       <mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle>
            <li class="mat-tree-node">
                <button mat-icon-button disabled></button>
                {{node.uniqueName}}
            </li>
        </mat-tree-node>

        <!--when has nested child-->
        <mat-nested-tree-node *matTreeNodeDef="let node; when: hasNestedChild">
            <li>
                <div class="mat-tree-node">
                    <button mat-icon-button matTreeNodeToggle>
                        <mat-icon>
                            {{nestedTreeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
                        </mat-icon>
                    </button>
                    {{node.uniqueName}}
                </div>
                <ul [class.invisible]="!nestedTreeControl.isExpanded(node)">
                    <ng-container matTreeNodeOutlet></ng-container>
                </ul>
            </li>
        </mat-nested-tree-node>
    </mat-tree>


  • {{node.uniqueName}
  • {{nestedTreeControl.isExpanded(节点)-'expand_more':'chevron_right'} {{node.uniqueName}

  • 我花了几个小时才让它工作起来,但以下是我所做的更改:

    // cdk tree that mat tree is based on has a bug causing children to not be rendered in the UI without first setting the data to null
    this.nestedDataSource.data = null;
    // mat-tree has some sort of memory leak issue when not instantiating a new MatTreeNestedDataSource which causes the app to become very slow
    this.nestedDataSource = new MatTreeNestedDataSource<LocationHierarchyNodeDataModel>();
    this.nestedDataSource.data = data;
    
    //mat-tree所基于的cdk-tree存在一个错误,导致在未将数据设置为null的情况下无法在UI中呈现子级
    this.nestedDataSource.data=null;
    //mat tree在没有实例化新的MattreenstedDataSource时存在某种内存泄漏问题,这会导致应用程序变得非常缓慢
    this.nestedDataSource=new MatTreeNestedDataSource();
    this.nestedDataSource.data=数据;
    

    我在这里发现的显示儿童问题:

    尽管公认的答案似乎提供了一些速度提升,但最终为我解决的解决方案(在Angular 8中)是:

    更改官方示例中的行:

    为此:


    因此,折叠的子树根本不会加载到DOM中。

    可以显示html吗?试着使用
    ngIf
    ,这样它就不会被加载到dom中。我不确定你的意思,但我已经编辑了这个问题,把它包括进去了。你节省了我的时间。感谢你的努力。谢谢:)哦,我的天啊,是的!昼夜差异。谢谢