@@ -193,6 +193,9 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
193193 new Map < K , CdkTreeNode < T , K > > ( ) ,
194194 ) ;
195195
196+ /** The mapping between data nodes and the parent node. `null` if no parent. */
197+ private _parents : Map < K , T | null > = new Map < K , T | null > ( ) ;
198+
196199 constructor ( private _differs : IterableDiffers , private _changeDetectorRef : ChangeDetectorRef ) { }
197200
198201 ngOnInit ( ) {
@@ -381,6 +384,7 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
381384 // Node context that will be provided to created embedded view
382385 const context = new CdkTreeNodeOutletContext < T > ( nodeData ) ;
383386
387+ parentData ??= this . _parents . get ( this . _trackExpansionKey ( nodeData ) ) ?? undefined ;
384388 // If the tree is flat tree, then use the `getLevel` function in flat tree control
385389 // Otherwise, use the level of parent node.
386390 const levelAccessor = this . _getLevelAccessor ( ) ;
@@ -596,6 +600,10 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
596600 this . _nodes . next ( this . _nodes . value ) ;
597601 }
598602
603+ _getLevel ( node : T ) {
604+ return this . _levels . get ( node ) ;
605+ }
606+
599607 /**
600608 * Gets all nodes in the tree, through recursive expansion.
601609 *
@@ -664,6 +672,10 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
664672 return coerceObservable ( this . childrenAccessor ( dataNode ) ) . pipe (
665673 take ( 1 ) ,
666674 switchMap ( children => {
675+ // Here, we cache the parents of a particular child so that we can compute the levels.
676+ for ( const child of children ) {
677+ this . _parents . set ( this . _trackExpansionKey ( child ) , dataNode ) ;
678+ }
667679 return observableOf ( ...children ) . pipe (
668680 concatMap ( child => concat ( observableOf ( [ child ] ) , this . _getAllChildrenRecursively ( child ) ) ) ,
669681 ) ;
@@ -772,7 +784,7 @@ export class CdkTreeNode<T, K = T> implements FocusableOption, OnDestroy, OnInit
772784 // If the tree has a levelAccessor, use it to get the level. Otherwise read the
773785 // aria-level off the parent node and use it as the level for this node (note aria-level is
774786 // 1-indexed, while this property is 0-indexed, so we don't need to increment).
775- return this . _tree . _getLevelAccessor ( ) ?. ( this . _data ) ?? this . _parentNodeAriaLevel ;
787+ return this . _tree . _getLevel ( this . _data ) ?? this . _parentNodeAriaLevel ;
776788 }
777789
778790 constructor ( protected _elementRef : ElementRef < HTMLElement > , protected _tree : CdkTree < T , K > ) {
0 commit comments