@@ -26,6 +26,7 @@ import {
2626import { Platform } from '@angular/cdk/platform' ;
2727import { ComponentPortal } from '@angular/cdk/portal' ;
2828import { take } from 'rxjs/operators/take' ;
29+ import { takeUntil } from 'rxjs/operators/takeUntil' ;
2930import { filter } from 'rxjs/operators/filter' ;
3031import {
3132 ChangeDetectionStrategy ,
@@ -188,6 +189,9 @@ export class MatTooltip implements OnDestroy {
188189
189190 private _manualListeners = new Map < string , Function > ( ) ;
190191
192+ /** Emits when the component is destroyed. */
193+ private readonly _destroyed = new Subject < void > ( ) ;
194+
191195 constructor (
192196 private _overlay : Overlay ,
193197 private _elementRef : ElementRef ,
@@ -224,7 +228,7 @@ export class MatTooltip implements OnDestroy {
224228 element . style . webkitUserSelect = element . style . userSelect = '' ;
225229 }
226230
227- _focusMonitor . monitor ( element ) . subscribe ( origin => {
231+ _focusMonitor . monitor ( element ) . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( origin => {
228232 // Note that the focus monitor runs outside the Angular zone.
229233 if ( ! origin ) {
230234 _ngZone . run ( ( ) => this . hide ( 0 ) ) ;
@@ -251,6 +255,9 @@ export class MatTooltip implements OnDestroy {
251255 this . _manualListeners . clear ( ) ;
252256 }
253257
258+ this . _destroyed . next ( ) ;
259+ this . _destroyed . complete ( ) ;
260+
254261 this . _ariaDescriber . removeDescription ( this . _elementRef . nativeElement , this . message ) ;
255262 this . _focusMonitor . stopMonitoring ( this . _elementRef . nativeElement ) ;
256263 }
@@ -264,7 +271,9 @@ export class MatTooltip implements OnDestroy {
264271 this . _detach ( ) ;
265272 this . _portal = this . _portal || new ComponentPortal ( TooltipComponent , this . _viewContainerRef ) ;
266273 this . _tooltipInstance = overlayRef . attach ( this . _portal ) . instance ;
267- this . _tooltipInstance . afterHidden ( ) . subscribe ( ( ) => this . _detach ( ) ) ;
274+ this . _tooltipInstance . afterHidden ( )
275+ . pipe ( takeUntil ( this . _destroyed ) )
276+ . subscribe ( ( ) => this . _detach ( ) ) ;
268277 this . _setTooltipClass ( this . _tooltipClass ) ;
269278 this . _updateTooltipMessage ( ) ;
270279 this . _tooltipInstance ! . show ( this . _position , delay ) ;
@@ -318,7 +327,10 @@ export class MatTooltip implements OnDestroy {
318327 this . _scrollDispatcher . getAncestorScrollContainers ( this . _elementRef )
319328 ) ;
320329
321- strategy . onPositionChange . pipe ( filter ( ( ) => ! ! this . _tooltipInstance ) ) . subscribe ( change => {
330+ strategy . onPositionChange . pipe (
331+ filter ( ( ) => ! ! this . _tooltipInstance ) ,
332+ takeUntil ( this . _destroyed )
333+ ) . subscribe ( change => {
322334 if ( change . scrollableViewProperties . isOverlayClipped && this . _tooltipInstance ! . isVisible ( ) ) {
323335 // After position changes occur and the overlay is clipped by
324336 // a parent scrollable then close the tooltip.
@@ -336,7 +348,9 @@ export class MatTooltip implements OnDestroy {
336348 scrollStrategy : this . _scrollStrategy ( )
337349 } ) ;
338350
339- this . _overlayRef . detachments ( ) . subscribe ( ( ) => this . _detach ( ) ) ;
351+ this . _overlayRef . detachments ( )
352+ . pipe ( takeUntil ( this . _destroyed ) )
353+ . subscribe ( ( ) => this . _detach ( ) ) ;
340354
341355 return this . _overlayRef ;
342356 }
@@ -429,7 +443,10 @@ export class MatTooltip implements OnDestroy {
429443 this . _tooltipInstance . message = this . message ;
430444 this . _tooltipInstance . _markForCheck ( ) ;
431445
432- this . _ngZone . onMicrotaskEmpty . asObservable ( ) . pipe ( take ( 1 ) ) . subscribe ( ( ) => {
446+ this . _ngZone . onMicrotaskEmpty . asObservable ( ) . pipe (
447+ take ( 1 ) ,
448+ takeUntil ( this . _destroyed )
449+ ) . subscribe ( ( ) => {
433450 if ( this . _tooltipInstance ) {
434451 this . _overlayRef ! . updatePosition ( ) ;
435452 }
0 commit comments