@@ -26,6 +26,7 @@ import {
26
26
import { Platform } from '@angular/cdk/platform' ;
27
27
import { ComponentPortal } from '@angular/cdk/portal' ;
28
28
import { take } from 'rxjs/operators/take' ;
29
+ import { takeUntil } from 'rxjs/operators/takeUntil' ;
29
30
import { filter } from 'rxjs/operators/filter' ;
30
31
import {
31
32
ChangeDetectionStrategy ,
@@ -188,6 +189,9 @@ export class MatTooltip implements OnDestroy {
188
189
189
190
private _manualListeners = new Map < string , Function > ( ) ;
190
191
192
+ /** Emits when the component is destroyed. */
193
+ private readonly _destroyed = new Subject < void > ( ) ;
194
+
191
195
constructor (
192
196
private _overlay : Overlay ,
193
197
private _elementRef : ElementRef ,
@@ -224,7 +228,7 @@ export class MatTooltip implements OnDestroy {
224
228
element . style . webkitUserSelect = element . style . userSelect = '' ;
225
229
}
226
230
227
- _focusMonitor . monitor ( element ) . subscribe ( origin => {
231
+ _focusMonitor . monitor ( element ) . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( origin => {
228
232
// Note that the focus monitor runs outside the Angular zone.
229
233
if ( ! origin ) {
230
234
_ngZone . run ( ( ) => this . hide ( 0 ) ) ;
@@ -251,6 +255,9 @@ export class MatTooltip implements OnDestroy {
251
255
this . _manualListeners . clear ( ) ;
252
256
}
253
257
258
+ this . _destroyed . next ( ) ;
259
+ this . _destroyed . complete ( ) ;
260
+
254
261
this . _ariaDescriber . removeDescription ( this . _elementRef . nativeElement , this . message ) ;
255
262
this . _focusMonitor . stopMonitoring ( this . _elementRef . nativeElement ) ;
256
263
}
@@ -264,7 +271,9 @@ export class MatTooltip implements OnDestroy {
264
271
this . _detach ( ) ;
265
272
this . _portal = this . _portal || new ComponentPortal ( TooltipComponent , this . _viewContainerRef ) ;
266
273
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 ( ) ) ;
268
277
this . _setTooltipClass ( this . _tooltipClass ) ;
269
278
this . _updateTooltipMessage ( ) ;
270
279
this . _tooltipInstance ! . show ( this . _position , delay ) ;
@@ -318,7 +327,10 @@ export class MatTooltip implements OnDestroy {
318
327
this . _scrollDispatcher . getAncestorScrollContainers ( this . _elementRef )
319
328
) ;
320
329
321
- strategy . onPositionChange . pipe ( filter ( ( ) => ! ! this . _tooltipInstance ) ) . subscribe ( change => {
330
+ strategy . onPositionChange . pipe (
331
+ filter ( ( ) => ! ! this . _tooltipInstance ) ,
332
+ takeUntil ( this . _destroyed )
333
+ ) . subscribe ( change => {
322
334
if ( change . scrollableViewProperties . isOverlayClipped && this . _tooltipInstance ! . isVisible ( ) ) {
323
335
// After position changes occur and the overlay is clipped by
324
336
// a parent scrollable then close the tooltip.
@@ -336,7 +348,9 @@ export class MatTooltip implements OnDestroy {
336
348
scrollStrategy : this . _scrollStrategy ( )
337
349
} ) ;
338
350
339
- this . _overlayRef . detachments ( ) . subscribe ( ( ) => this . _detach ( ) ) ;
351
+ this . _overlayRef . detachments ( )
352
+ . pipe ( takeUntil ( this . _destroyed ) )
353
+ . subscribe ( ( ) => this . _detach ( ) ) ;
340
354
341
355
return this . _overlayRef ;
342
356
}
@@ -429,7 +443,10 @@ export class MatTooltip implements OnDestroy {
429
443
this . _tooltipInstance . message = this . message ;
430
444
this . _tooltipInstance . _markForCheck ( ) ;
431
445
432
- this . _ngZone . onMicrotaskEmpty . asObservable ( ) . pipe ( take ( 1 ) ) . subscribe ( ( ) => {
446
+ this . _ngZone . onMicrotaskEmpty . asObservable ( ) . pipe (
447
+ take ( 1 ) ,
448
+ takeUntil ( this . _destroyed )
449
+ ) . subscribe ( ( ) => {
433
450
if ( this . _tooltipInstance ) {
434
451
this . _overlayRef ! . updatePosition ( ) ;
435
452
}
0 commit comments