Angular 9集成Angular Tree Component 9.0.5初始化报错如何解决?
问题根因
- 初始化时序缺陷:Angular Tree Component v9.0.5本身存在逻辑漏洞,输入属性
nodes的赋值回调未做实例存在性守卫,会在内部VirtualRoot、VirtualScroll实例挂载完成前就尝试访问这两个对象,直接触发初始化报错。 - 状态响应冲突:该树组件内部使用Mobx做内部状态的响应式更新,而Redux的不可变状态更新逻辑会改变Angular变更检测的触发时序,导致Mobx的响应式订阅无法正常触发,即使
TreeModel内部数据已经更新,也无法通知视图重新渲染。
解决方案
- 新增渲染守卫规避初始化时序问题
在TS文件中新增isTreeReady状态,在ngAfterViewInit生命周期钩子中再将状态置为true,模板中通过*ngIf控制树组件的渲染时机,确保组件实例完全初始化完成后再传入节点数据。如果你的节点数量不多,可以直接关闭虚拟滚动,从根源绕开Virtual相关对象的初始化问题:<!-- 模板代码 --> <tree-root *ngIf="isTreeReady" [nodes]="nodes" #tree [useVirtualScroll]="false"></tree-root>// TS代码 import { Component, AfterViewInit } from '@angular/core'; @Component({/* 你的组件配置 */}) export class YourComponent implements AfterViewInit { isTreeReady = false; nodes: any[] = []; ngAfterViewInit(): void { this.isTreeReady = true; // 在这里赋值节点数据,或者从Redux中取数后赋值 this.nodes = [{name:'Test root node', children: []}]; } } - 手动触发更新与变更检测
如果需要保留虚拟滚动能力,更新节点数据后除了调用this.tree.treeModel.update(),额外手动触发Mobx更新事件与Angular变更检测即可完成视图渲染:import { ChangeDetectorRef } from '@angular/core'; constructor(private cdr: ChangeDetectorRef) {} updateTreeNodes(newNodes: any[]): void { this.nodes = newNodes; this.tree.treeModel.update(); // 触发树组件内部的更新事件 this.tree.treeModel.fireEvent({ eventName: 'update' }); // 手动触发当前组件的变更检测 this.cdr.detectChanges(); } - 适配Mobx运行环境(可选,适用于项目单独安装了Mobx的场景)
在根模块中配置Mobx的运行上下文,确保Mobx的响应式回调在Angular Zone中执行,能够正常触发视图更新:import { NgZone, APP_INITIALIZER } from '@angular/core'; import { configure } from 'mobx'; export function mobxConfig(ngZone: NgZone) { return () => configure({ reactionScheduler: (fn) => ngZone.isInAngularZone() ? fn() : ngZone.run(fn) }); } // 根模块providers中添加配置 providers: [ { provide: APP_INITIALIZER, useFactory: mobxConfig, deps: [NgZone], multi: true } ]
内容的提问来源于stack exchange,提问作者Ulad Melekh
相关产品推荐
相关产品推荐

