@@ -17,6 +17,9 @@ import {
1717 Optional ,
1818 QueryList ,
1919 ViewEncapsulation ,
20+ OnChanges ,
21+ OnDestroy ,
22+ ChangeDetectorRef ,
2023} from '@angular/core' ;
2124import {
2225 CanDisableRipple ,
@@ -25,6 +28,8 @@ import {
2528 setLines ,
2629 mixinDisableRipple ,
2730} from '@angular/material/core' ;
31+ import { Subject } from 'rxjs' ;
32+ import { takeUntil } from 'rxjs/operators' ;
2833
2934// Boilerplate for applying mixins to MatList.
3035/** @docs -private */
@@ -52,7 +57,19 @@ export const _MatListItemMixinBase: CanDisableRippleCtor & typeof MatListItemBas
5257 encapsulation : ViewEncapsulation . None ,
5358 changeDetection : ChangeDetectionStrategy . OnPush ,
5459} )
55- export class MatNavList extends _MatListMixinBase implements CanDisableRipple { }
60+ export class MatNavList extends _MatListMixinBase implements CanDisableRipple , OnChanges ,
61+ OnDestroy {
62+ /** Emits when the state of the list changes. */
63+ _stateChanges = new Subject < void > ( ) ;
64+
65+ ngOnChanges ( ) {
66+ this . _stateChanges . next ( ) ;
67+ }
68+
69+ ngOnDestroy ( ) {
70+ this . _stateChanges . complete ( ) ;
71+ }
72+ }
5673
5774@Component ( {
5875 moduleId : module . id ,
@@ -67,7 +84,10 @@ export class MatNavList extends _MatListMixinBase implements CanDisableRipple {}
6784 encapsulation : ViewEncapsulation . None ,
6885 changeDetection : ChangeDetectionStrategy . OnPush ,
6986} )
70- export class MatList extends _MatListMixinBase implements CanDisableRipple {
87+ export class MatList extends _MatListMixinBase implements CanDisableRipple , OnChanges , OnDestroy {
88+ /** Emits when the state of the list changes. */
89+ _stateChanges = new Subject < void > ( ) ;
90+
7191 /**
7292 * @deprecated _elementRef parameter to be made required.
7393 * @breaking -change 8.0.0
@@ -94,6 +114,14 @@ export class MatList extends _MatListMixinBase implements CanDisableRipple {
94114
95115 return null ;
96116 }
117+
118+ ngOnChanges ( ) {
119+ this . _stateChanges . next ( ) ;
120+ }
121+
122+ ngOnDestroy ( ) {
123+ this . _stateChanges . complete ( ) ;
124+ }
97125}
98126
99127/**
@@ -143,17 +171,20 @@ export class MatListSubheaderCssMatStyler {}
143171 changeDetection : ChangeDetectionStrategy . OnPush ,
144172} )
145173export class MatListItem extends _MatListItemMixinBase implements AfterContentInit ,
146- CanDisableRipple {
174+ CanDisableRipple , OnDestroy {
147175 private _isInteractiveList : boolean = false ;
148176 private _list ?: MatNavList | MatList ;
177+ private _destroyed = new Subject < void > ( ) ;
149178
150179 @ContentChildren ( MatLine ) _lines : QueryList < MatLine > ;
151180 @ContentChild ( MatListAvatarCssMatStyler ) _avatar : MatListAvatarCssMatStyler ;
152181 @ContentChild ( MatListIconCssMatStyler ) _icon : MatListIconCssMatStyler ;
153182
154183 constructor ( private _element : ElementRef < HTMLElement > ,
155184 @Optional ( ) navList ?: MatNavList ,
156- @Optional ( ) list ?: MatList ) {
185+ @Optional ( ) list ?: MatList ,
186+ // @breaking -change 8.0.0 `_changeDetectorRef` to be made into a required parameter.
187+ _changeDetectorRef ?: ChangeDetectorRef ) {
157188 super ( ) ;
158189 this . _isInteractiveList = ! ! ( navList || ( list && list . _getListType ( ) === 'action-list' ) ) ;
159190 this . _list = navList || list ;
@@ -165,12 +196,26 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn
165196 if ( element . nodeName . toLowerCase ( ) === 'button' && ! element . hasAttribute ( 'type' ) ) {
166197 element . setAttribute ( 'type' , 'button' ) ;
167198 }
199+
200+ // @breaking -change 8.0.0 Remove null check for _changeDetectorRef.
201+ if ( this . _list && _changeDetectorRef ) {
202+ // React to changes in the state of the parent list since
203+ // some of the item's properties depend on it (e.g. `disableRipple`).
204+ this . _list . _stateChanges . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( ( ) => {
205+ _changeDetectorRef . markForCheck ( ) ;
206+ } ) ;
207+ }
168208 }
169209
170210 ngAfterContentInit ( ) {
171211 setLines ( this . _lines , this . _element ) ;
172212 }
173213
214+ ngOnDestroy ( ) {
215+ this . _destroyed . next ( ) ;
216+ this . _destroyed . complete ( ) ;
217+ }
218+
174219 /** Whether this list item should show a ripple effect when clicked. */
175220 _isRippleDisabled ( ) {
176221 return ! this . _isInteractiveList || this . disableRipple ||
0 commit comments