From 75911db8debfac905de9336d827a0af6f70dd998 Mon Sep 17 00:00:00 2001 From: Wendell Hu Date: Wed, 5 Feb 2020 09:58:37 +0800 Subject: [PATCH] feat(cdk/overlay): directive support disposeOnNavigation --- src/cdk/overlay/overlay-directives.spec.ts | 37 +++++++++++++++++++--- src/cdk/overlay/overlay-directives.ts | 13 ++++++++ tools/public_api_guard/cdk/overlay.md | 4 ++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/cdk/overlay/overlay-directives.spec.ts b/src/cdk/overlay/overlay-directives.spec.ts index 60199ffc6052..b5d198a882fd 100644 --- a/src/cdk/overlay/overlay-directives.spec.ts +++ b/src/cdk/overlay/overlay-directives.spec.ts @@ -1,4 +1,6 @@ import {Component, ElementRef, ViewChild} from '@angular/core'; +import {Location} from '@angular/common'; +import {SpyLocation} from '@angular/common/testing'; import {By} from '@angular/platform-browser'; import { ComponentFixture, @@ -36,6 +38,7 @@ describe('Overlay directives', () => { let fixture: ComponentFixture; let dir: {value: string}; let scrolledSubject = new Subject(); + let mockLocation: SpyLocation; beforeEach(() => { TestBed.configureTestingModule({ @@ -49,6 +52,10 @@ describe('Overlay directives', () => { scrolled: () => scrolledSubject, }), }, + { + provide: Location, + useClass: SpyLocation, + }, ], }); }); @@ -58,10 +65,14 @@ describe('Overlay directives', () => { fixture.detectChanges(); }); - beforeEach(inject([OverlayContainer, Overlay], (oc: OverlayContainer, o: Overlay) => { - overlay = o; - overlayContainerElement = oc.getContainerElement(); - })); + beforeEach(inject( + [OverlayContainer, Overlay, Location], + (oc: OverlayContainer, o: Overlay, l: Location) => { + overlay = o; + overlayContainerElement = oc.getContainerElement(); + mockLocation = l as SpyLocation; + }, + )); /** Returns the current open overlay pane element. */ function getPaneElement() { @@ -383,6 +394,20 @@ describe('Overlay directives', () => { expect(pane.style.transform).toContain('translateY(55px)'); }); + it('should support dispose on navigation', () => { + const testComponent = fixture.componentInstance; + + fixture.componentInstance.isOpen = true; + testComponent.disposeOnNavigation = true; + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Menu content'); + + mockLocation.simulateUrlPop(''); + expect(overlayContainerElement.childNodes.length).toBe(0); + expect(overlayContainerElement.textContent).toBe(''); + }); + it('should be able to update the origin after init', () => { const testComponent = fixture.componentInstance; @@ -723,7 +748,8 @@ describe('Overlay directives', () => { [cdkConnectedOverlayMinWidth]="minWidth" [cdkConnectedOverlayMinHeight]="minHeight" [cdkConnectedOverlayPositions]="positionOverrides" - [cdkConnectedOverlayTransformOriginOn]="transformOriginSelector"> + [cdkConnectedOverlayTransformOriginOn]="transformOriginSelector" + [cdkConnectedOverlayDisposeOnNavigation]="disposeOnNavigation">

Menu content

`, }) @@ -760,6 +786,7 @@ class ConnectedOverlayDirectiveTest { detachHandler = jasmine.createSpy('detachHandler'); attachResult: HTMLElement; transformOriginSelector: string; + disposeOnNavigation = false; } @Component({ diff --git a/src/cdk/overlay/overlay-directives.ts b/src/cdk/overlay/overlay-directives.ts index cfbb6909d888..af184c440e4a 100644 --- a/src/cdk/overlay/overlay-directives.ts +++ b/src/cdk/overlay/overlay-directives.ts @@ -110,6 +110,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { private _offsetY: number; private _position: FlexibleConnectedPositionStrategy; private _scrollStrategyFactory: () => ScrollStrategy; + private _disposeOnNavigation = false; /** Origin for the connected overlay. */ @Input('cdkConnectedOverlayOrigin') @@ -228,6 +229,17 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { this._push = coerceBooleanProperty(value); } + /** + * Whether the overlay should be disposed of when the user goes backwards/forwards in history. + */ + @Input('cdkConnectedOverlayDisposeOnNavigation') + get disposeOnNavigation(): boolean { + return this._disposeOnNavigation; + } + set disposeOnNavigation(value: boolean) { + this._disposeOnNavigation = coerceBooleanProperty(value); + } + /** Event emitted when the backdrop is clicked. */ @Output() readonly backdropClick = new EventEmitter(); @@ -333,6 +345,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { positionStrategy, scrollStrategy: this.scrollStrategy, hasBackdrop: this.hasBackdrop, + disposeOnNavigation: this.disposeOnNavigation, }); if (this.width || this.width === 0) { diff --git a/tools/public_api_guard/cdk/overlay.md b/tools/public_api_guard/cdk/overlay.md index e6f7a560cebc..97c2ba51254d 100644 --- a/tools/public_api_guard/cdk/overlay.md +++ b/tools/public_api_guard/cdk/overlay.md @@ -67,6 +67,8 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { readonly detach: EventEmitter; get dir(): Direction; disableClose: boolean; + get disposeOnNavigation(): boolean; + set disposeOnNavigation(value: boolean); get flexibleDimensions(): boolean; set flexibleDimensions(value: BooleanInput); get growAfterOpen(): boolean; @@ -102,7 +104,7 @@ export class CdkConnectedOverlay implements OnDestroy, OnChanges { viewportMargin: number; width: number | string; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration; + static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; }