tutorial に従ってcdkツリーをangular 6.で実装します。ツリー構造を作成しました。ノードの子を取得するgetDescendantsなどのメソッドがありますが、その逆は利用できません。子またはリーフノードから親階層を取得するにはどうすればよいですか。
これらのメソッドをツリーコンポーネントに追加しました。フラットツリーを使用していることに注意してください。これはネストされたツリーでは機能しません。
@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;
}
}
}
}
独自のFlatTreeControl
を作成し(Angular CDKのFlatTreeControl
を拡張することにより)、そこにこのロジックを移動することを計画しています。
[〜#〜] update [〜#〜]
上記のロジックを自分の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;
}
}
}
}
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;
}
}
}
}
親階層は、各番号がネストされた再帰ノードのインデックスである番号の配列に格納できます。指定されたノードでツリーを展開するために、以前の例を使用しようとしましたが、最終的にはそのようにすることにしました:
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)次に、ツリーが折りたたまれたとき、nodePathのすべてのアイテムの展開を呼び出す必要があります(ツリーが折りたたまれた場合、展開したくないノードが削除されるため、最後の要素はパスから削除されます)。
expandTreeOnSpecifiedNode(isDelete: boolean) {
if (isDelete) {
this.nodePath.pop();
}
this.nodePath.forEach(id => {
console.log(id);
this.treeControl.expand(this.treeControl.dataNodes[id]);
});
}