Skip to content

Commit 7fe651b

Browse files
crisbetotinayuangao
authored andcommitted
fix(overlay): onPositionChange stream not being completed (#8562)
Completes the `onPositionChange` stream when the position strategy is disposed. Also cleans up a few cases that were unsubscribing from it explicitly.
1 parent 1417387 commit 7fe651b

File tree

4 files changed

+19
-7
lines changed

4 files changed

+19
-7
lines changed

src/cdk/overlay/overlay-directives.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
9898
private _templatePortal: TemplatePortal;
9999
private _hasBackdrop = false;
100100
private _backdropSubscription = Subscription.EMPTY;
101-
private _positionSubscription = Subscription.EMPTY;
102101
private _offsetX: number = 0;
103102
private _offsetY: number = 0;
104103
private _position: ConnectedPositionStrategy;
@@ -369,8 +368,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
369368
);
370369
}
371370

372-
this._positionSubscription = strategy.onPositionChange
373-
.subscribe(pos => this.positionChange.emit(pos));
371+
strategy.onPositionChange.subscribe(pos => this.positionChange.emit(pos));
374372

375373
return strategy;
376374
}
@@ -419,6 +417,5 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges {
419417
}
420418

421419
this._backdropSubscription.unsubscribe();
422-
this._positionSubscription.unsubscribe();
423420
}
424421
}

src/cdk/overlay/position/connected-position-strategy.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,22 @@ describe('ConnectedPositionStrategy', () => {
407407
subscription.unsubscribe();
408408
});
409409

410+
it('should complete the onPositionChange stream on dispose', () => {
411+
strategy = positionBuilder.connectedTo(
412+
fakeElementRef,
413+
{originX: 'end', originY: 'bottom'},
414+
{overlayX: 'start', overlayY: 'top'});
415+
416+
const completeHandler = jasmine.createSpy('complete handler');
417+
418+
strategy.onPositionChange.subscribe(undefined, undefined, completeHandler);
419+
strategy.attach(fakeOverlayRef(overlayElement));
420+
strategy.apply();
421+
strategy.dispose();
422+
423+
expect(completeHandler).toHaveBeenCalled();
424+
});
425+
410426
it('should pick the fallback position that shows the largest area of the element', () => {
411427
originElement.style.top = '200px';
412428
originElement.style.right = '25px';

src/cdk/overlay/position/connected-position-strategy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export class ConnectedPositionStrategy implements PositionStrategy {
108108
dispose() {
109109
this._applied = false;
110110
this._resizeSubscription.unsubscribe();
111+
this._onPositionChange.complete();
111112
}
112113

113114
/** @docs-private */

src/lib/menu/menu-trigger.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
8787
private _overlayRef: OverlayRef | null = null;
8888
private _menuOpen: boolean = false;
8989
private _closeSubscription = Subscription.EMPTY;
90-
private _positionSubscription = Subscription.EMPTY;
9190
private _hoverSubscription = Subscription.EMPTY;
9291

9392
// Tracking input type is necessary so it's possible to only auto-focus
@@ -353,7 +352,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
353352
* correct, even if a fallback position is used for the overlay.
354353
*/
355354
private _subscribeToPositions(position: ConnectedPositionStrategy): void {
356-
this._positionSubscription = position.onPositionChange.subscribe(change => {
355+
position.onPositionChange.subscribe(change => {
357356
const posX: MenuPositionX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
358357
const posY: MenuPositionY = change.connectionPair.overlayY === 'top' ? 'below' : 'above';
359358

@@ -408,7 +407,6 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
408407
/** Cleans up the active subscriptions. */
409408
private _cleanUpSubscriptions(): void {
410409
this._closeSubscription.unsubscribe();
411-
this._positionSubscription.unsubscribe();
412410
this._hoverSubscription.unsubscribe();
413411
}
414412

0 commit comments

Comments
 (0)