如何解决ngOnChanges 只击中树的根,而不是所有的后代
我的父组件有一个非二叉树节点(树的根)作为子节点。 每个节点可以有 0 个或多个节点类型的子节点,子节点可以折叠或展开。 此外,在我的父组件中,有一个按钮可让您全部折叠或展开所有树中所有节点的子级。
我有一个枚举来标记整个树是折叠(通过按钮),整个树是展开(通过按钮),还是手动控制树状态(这与此问题无关)。>
枚举看起来像这样:
export enum TreeStatus{
Collapsed,Expanded,Manual
}
parent.component.ts:
export class ParentComponent implements OnInit {
root: Node;
public treeStatus= TreeStatus.Collapsed; //in the beginning,every node in the tree has children collapsed
public isAnynodechildrenCollapsed = true; //checks if any node has children collapsed(mainly used for manual toggle)
onExpandAll() {
this.treeStatus= TreeStatus.Expanded;
this.isAnynodechildrenCollapsed = false;
}
onCollapseAll(){
this.treeStatus= TreeStatus.Collapsed;
this.isAnynodechildrenCollapsed = true;
}
...
}
parent.component.html:
<div>
<button *ngIf="!isAnynodechildrenCollapsed " (click)="onCollapseAll()"> //if all nodes have children expanded,we will see the button that allows us to collapse all
Collapse All
</button>
<button *ngIf="isAnynodechildrenCollapsed " (click)="onExpandAll()"> //if at least one node has children collapsed,we will see the button that allows us to expand all
Expand All
</button>
</div>
<div>
<tree-item [node]="root" [treeStatus]="treeStatus"></tree-item> //the root of my tree
</div>
tree-item.component.ts:
export class TreeItemComponent implements OnInit,OnChanges{
@input() node: Node;
@input() treeStatus: TreeStatus;
public isChildrenCollapsed = true; //initially,all nodes have children collapsed
ngOnChanges(changes: SimpleChanges) {
console.log(this.node.id + ": " + changes.treeStatus.prevIoUsValue + " => " + changes.TreeStatus.currentValue);
//this log above best displays the issue. When I click on Expand All,all nodes in my tree appear in the logs,but when I click Collapse All,even though this is the same callback method,only the root appears to detect the change.(even so,the toggle somehow happens regardless)
if (changes.treeStatus && changes.treeStatus.currentValue!=NavigatorTreeStatus.Manual) {
this.isChildrenCollapsed = !(changes.treeStatus.currentValue == NavigatorTreeStatus.Expanded);
}
}
}
}
tree-item.component.html(基本DFS树解析):
<div>
//display node here
</div>
<div *ngIf="node.children.length > 0 && !isChildrenCollapsed">
<tree-item *ngFor="let child of node.children"
[node]="child"
[treeStatus]="treeStatus"
>
</div>
我只是不明白为什么,当我点击全部展开,从而将 treeStatus 更改为已展开时,ngOnChanged 正常工作并按预期运行,传播到三个节点中的每个节点,但是当点击 Collapse All 现在会触发相同的 ngOnChanges 回调方法,唯一检测到更改的节点似乎是根。
以下是日志的显示方式: 最初,当打开组件时,root id 的状态为 0(已折叠),而不是未定义:
2013777645:未定义 => 0
点击Expand All后,root Id的值从0(Collapsed)变为1(Expanded),其余节点从undefined变为1(Expanded)
2013777645:0 => 1
2118369458:未定义 => 1
368241412:未定义 => 1
1860836078:未定义 => 1
1979885541:未定义 => 1
1316570423:未定义 => 1
360484732:未定义 => 1
506271756:未定义 => 1
现在,在点击全部折叠后,日志中只出现根,将值从 1(展开)更改为 0(折叠)。
2013777645:1 => 0
最后,如果我们现在再次点击Expand All,会出现与之前完全相同的日志,即使其他节点不应该为 treeStatus 设置未定义的值,因为它之前已被赋值.
2013777645:0 => 1
2118369458:未定义 => 1
368241412:未定义 => 1
1860836078:未定义 => 1
1979885541:未定义 => 1
1316570423:未定义 => 1
360484732:未定义 => 1
506271756:未定义 => 1
你能帮我理解我遗漏了什么吗? 我真的希望你能从这个解释中理解这个问题。 提前致谢!
解决方法
看起来你用 ngIf
隐藏了子节点。当 ngIf
为 false 时,您的组件(或模板)不仅被隐藏,而且被销毁。您可以找到更多详情here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。