@@ -54,6 +54,7 @@ import {
5454 take ,
5555 takeUntil ,
5656 tap ,
57+ withLatestFrom ,
5758} from 'rxjs/operators' ;
5859import { TreeControl } from './control/tree-control' ;
5960import { CdkTreeNodeDef , CdkTreeNodeOutletContext } from './node' ;
@@ -260,9 +261,26 @@ export class CdkTree<T, K = T>
260261 }
261262 }
262263
264+ let expansionModel ;
263265 if ( ! this . treeControl ) {
264- this . _expansionModel = new SelectionModel ( true ) ;
266+ expansionModel = new SelectionModel < K > ( true ) ;
267+ this . _expansionModel = expansionModel ;
268+ } else {
269+ expansionModel = this . treeControl . expansionModel ;
265270 }
271+
272+ // We manually detect changes on all the children nodes when expansion
273+ // status changes; otherwise, the various attributes won't be updated.
274+ expansionModel . changed
275+ . pipe ( withLatestFrom ( this . _nodes ) , takeUntil ( this . _onDestroy ) )
276+ . subscribe ( ( [ changes , nodes ] ) => {
277+ for ( const added of changes . added ) {
278+ nodes . get ( added ) ?. _changeDetectorRef . detectChanges ( ) ;
279+ }
280+ for ( const removed of changes . removed ) {
281+ nodes . get ( removed ) ?. _changeDetectorRef . detectChanges ( ) ;
282+ }
283+ } ) ;
266284 }
267285
268286 ngOnDestroy ( ) {
@@ -986,13 +1004,21 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
9861004 return this . _tree . _getLevel ( this . _data ) ?? this . _parentNodeAriaLevel ;
9871005 }
9881006
1007+ /** Determines if the tree node is expandable. */
1008+ _isExpandable ( ) : boolean {
1009+ if ( typeof this . _tree . treeControl ?. isExpandable === 'function' ) {
1010+ return this . _tree . treeControl . isExpandable ( this . _data ) ;
1011+ }
1012+ return this . isExpandable ;
1013+ }
1014+
9891015 /**
9901016 * Determines the value for `aria-expanded`.
9911017 *
9921018 * For non-expandable nodes, this is `null`.
9931019 */
9941020 _getAriaExpanded ( ) : string | null {
995- if ( ! this . isExpandable ) {
1021+ if ( ! this . _isExpandable ( ) ) {
9961022 return null ;
9971023 }
9981024 return String ( this . isExpanded ) ;
@@ -1016,7 +1042,11 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
10161042 return this . _tree . _getPositionInSet ( this . _data ) ;
10171043 }
10181044
1019- constructor ( protected _elementRef : ElementRef < HTMLElement > , protected _tree : CdkTree < T , K > ) {
1045+ constructor (
1046+ protected _elementRef : ElementRef < HTMLElement > ,
1047+ protected _tree : CdkTree < T , K > ,
1048+ public _changeDetectorRef : ChangeDetectorRef ,
1049+ ) {
10201050 CdkTreeNode . mostRecentTreeNode = this as CdkTreeNode < T , K > ;
10211051 this . role = 'treeitem' ;
10221052 }
0 commit comments