@@ -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 private _getAllDescendants ( ) : Observable < T [ ] > {
600608 return merge ( ...this . _dataNodes . value . map ( dataNode => this . _getDescendants ( dataNode ) ) ) ;
601609 }
@@ -653,6 +661,10 @@ export class CdkTree<T, K = T> implements AfterContentChecked, CollectionViewer,
653661 return coerceObservable ( this . childrenAccessor ( dataNode ) ) . pipe (
654662 take ( 1 ) ,
655663 switchMap ( children => {
664+ // Here, we cache the parents of a particular child so that we can compute the levels.
665+ for ( const child of children ) {
666+ this . _parents . set ( this . _trackExpansionKey ( child ) , dataNode ) ;
667+ }
656668 return observableOf ( ...children ) . pipe (
657669 concatMap ( child => concat ( observableOf ( [ child ] ) , this . _getAllChildrenRecursively ( child ) ) ) ,
658670 ) ;
@@ -761,7 +773,7 @@ export class CdkTreeNode<T, K = T> implements FocusableOption, OnDestroy, OnInit
761773 // If the tree has a levelAccessor, use it to get the level. Otherwise read the
762774 // aria-level off the parent node and use it as the level for this node (note aria-level is
763775 // 1-indexed, while this property is 0-indexed, so we don't need to increment).
764- return this . _tree . _getLevelAccessor ( ) ?. ( this . _data ) ?? this . _parentNodeAriaLevel ;
776+ return this . _tree . _getLevel ( this . _data ) ?? this . _parentNodeAriaLevel ;
765777 }
766778
767779 constructor ( protected _elementRef : ElementRef < HTMLElement > , protected _tree : CdkTree < T , K > ) {
0 commit comments