typescript 从 angular 6 材质树中的子节点获取父层次结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51324524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get parent hierarchy from a child node in angular 6 material tree
提问by user9040429
I am following a tutorialto implement cdk tree in angular 6. I created a tree structure, now I want to get the parent hierarchy from from the child by making it clickable, while there are methods like getDescendants to get children of a node, vice versa is not available. How can I get the parent hierarchy from a child or leaf node.
我正在学习在 angular 6 中实现 cdk 树的教程。我创建了一个树结构,现在我想通过使其可点击来从子级获取父级层次结构,同时还有像 getDescendants 这样的方法来获取节点的子级,副反之亦然不可用。如何从子节点或叶节点获取父层次结构。
回答by Flauwekeul
I've added these methods to my tree component. Note that I use the flat tree, this won't work for a nested tree.
我已将这些方法添加到我的树组件中。请注意,我使用扁平树,这不适用于嵌套树。
@Component({
selector: 'es-outline-tree',
// ...
})
export class OutlineTreeComponent implements OnInit {
treeControl: FlatTreeControl<FlatTreeNode>;
// other code...
/**
* Recursively expand all parents of the passed node.
*/
expandParents(node: FlatTreeNode) {
const parent = this.getParent(node);
this.treeControl.expand(parent);
if (parent && parent.level > 0) {
this.expandParents(parent);
}
}
/**
* Iterate over each node in reverse order and return the first node that has a lower level than the passed node.
*/
getParent(node: FlatTreeNode) {
const { treeControl } = this;
const currentLevel = treeControl.getLevel(node);
if (currentLevel < 1) {
return null;
}
const startIndex = treeControl.dataNodes.indexOf(node) - 1;
for (let i = startIndex; i >= 0; i--) {
const currentNode = treeControl.dataNodes[i];
if (treeControl.getLevel(currentNode) < currentLevel) {
return currentNode;
}
}
}
}
I'm planning to create my own FlatTreeControl
(by extending Angular CDK's FlatTreeControl
) and move this logic there.
我计划创建我自己的FlatTreeControl
(通过扩展 Angular CDK's FlatTreeControl
)并将这个逻辑移到那里。
UPDATE
更新
I've moved the above logic to my own FlatTreeControl
implementation:
我已将上述逻辑移至我自己的FlatTreeControl
实现中:
import { FlatTreeControl } from '@angular/cdk/tree';
export class CustomTreeControl<T> extends FlatTreeControl<T> {
/**
* Recursively expand all parents of the passed node.
*/
expandParents(node: T) {
const parent = this.getParent(node);
this.expand(parent);
if (parent && this.getLevel(parent) > 0) {
this.expandParents(parent);
}
}
/**
* Iterate over each node in reverse order and return the first node that has a lower level than the passed node.
*/
getParent(node: T) {
const currentLevel = this.getLevel(node);
if (currentLevel < 1) {
return null;
}
const startIndex = this.dataNodes.indexOf(node) - 1;
for (let i = startIndex; i >= 0; i--) {
const currentNode = this.dataNodes[i];
if (this.getLevel(currentNode) < currentLevel) {
return currentNode;
}
}
}
}
回答by flosej
Thanks to Flauwekeul, a little bit simplified
感谢 Flauwekeul,稍微简化了一点
import { FlatTreeControl } from '@angular/cdk/tree';
export class CustomTreeControl<T> extends FlatTreeControl<T> {
/**
* Iterate over each node in reverse order and expand each inferior level nodes until level 0.
*/
expandParents(node: any) {
const currentLevel = this.getLevel(node);
if (currentLevel < 1) {
return null;
}
const startIndex = this.dataNodes.indexOf(node) - 1;
for (let i = startIndex; i >= 0; i--) {
const currentNode = this.dataNodes[i];
if (this.getLevel(currentNode) < currentLevel) {
this.expand(currentNode);
if (this.getLevel(currentNode) === 0) break;
}
}
}
}
回答by greygreg87
Parent hierarchy can be stored in Array of numbers where each number is index of reccurent nested node. In order to expand tree on specified node I tried use previous examples, but eventually I decided make it that way:
父层次结构可以存储在数字数组中,其中每个数字都是重复嵌套节点的索引。为了在指定节点上扩展树,我尝试使用前面的示例,但最终我决定这样做:
1) ChangePath must be call every time we click on node:
1)每次点击节点时都必须调用ChangePath:
changePath(node) {
if (node.level < this.nodePath.length) {
this.nodePath.splice(node.level, this.nodePath.length - node.level);
}
this.nodePath.push(this.treeControl.dataNodes.indexOf(node));}
2) Next, when tree collapses, we must call expand of every item in nodePath (when tree collapse in is caused by delete node we dont want expand it, so last element is removed from path):
2)接下来,当树折叠时,我们必须调用nodePath中每个项目的expand(当树折叠是由删除节点引起的我们不想扩展它,所以从路径中删除最后一个元素):
expandTreeOnSpecifiedNode(isDelete: boolean) {
if (isDelete) {
this.nodePath.pop();
}
this.nodePath.forEach(id => {
console.log(id);
this.treeControl.expand(this.treeControl.dataNodes[id]);
});
}