Skip to content

Commit 84d8f5b

Browse files
crisbetovivian-hu-zz
authored andcommitted
fix(experimental/dialog): clean up open dialogs on destroy (#13421)
Cleans up all of the open dialogs when a dialog from `cdk-experimental/dialog` is destroyed.
1 parent 2ed1916 commit 84d8f5b

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/cdk-experimental/dialog/dialog.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,20 @@ describe('Dialog', () => {
618618
expect(spy).toHaveBeenCalled();
619619
}));
620620

621+
it('should close all open dialogs on destroy', fakeAsync(() => {
622+
dialog.openFromComponent(PizzaMsg, { viewContainerRef: testViewContainerRef });
623+
dialog.openFromComponent(PizzaMsg, { viewContainerRef: testViewContainerRef });
624+
625+
viewContainerFixture.detectChanges();
626+
expect(overlayContainerElement.querySelectorAll('cdk-dialog-container').length).toBe(2);
627+
628+
dialog.ngOnDestroy();
629+
viewContainerFixture.detectChanges();
630+
flush();
631+
632+
expect(overlayContainerElement.querySelectorAll('cdk-dialog-container').length).toBe(0);
633+
}));
634+
621635
describe('passing in data', () => {
622636
it('should be able to pass in data', () => {
623637
let config = {
@@ -991,6 +1005,22 @@ describe('Dialog with a parent Dialog', () => {
9911005
.toBe('', 'Expected closeAll on parent Dialog to close dialog opened by child');
9921006
}));
9931007

1008+
it('should not close the parent dialogs, when a child is destroyed', fakeAsync(() => {
1009+
parentDialog.openFromComponent(PizzaMsg);
1010+
fixture.detectChanges();
1011+
flush();
1012+
1013+
expect(overlayContainerElement.textContent)
1014+
.toContain('Pizza', 'Expected a dialog to be opened');
1015+
1016+
childDialog.ngOnDestroy();
1017+
fixture.detectChanges();
1018+
flush();
1019+
1020+
expect(overlayContainerElement.textContent)
1021+
.toContain('Pizza', 'Expected a dialog to remain opened');
1022+
}));
1023+
9941024
it('should close the top dialog via the escape key', fakeAsync(() => {
9951025
childDialog.openFromComponent(PizzaMsg);
9961026
fixture.detectChanges();

src/cdk-experimental/dialog/dialog.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {
1313
Injectable,
1414
Injector,
1515
Inject,
16-
ComponentRef
16+
ComponentRef,
17+
OnDestroy
1718
} from '@angular/core';
1819
import {ComponentPortal, PortalInjector, TemplatePortal} from '@angular/cdk/portal';
1920
import {of as observableOf, Observable, Subject, defer} from 'rxjs';
@@ -43,7 +44,7 @@ import {
4344
* Service to open modal dialogs.
4445
*/
4546
@Injectable()
46-
export class Dialog {
47+
export class Dialog implements OnDestroy {
4748
/** Stream that emits when all dialogs are closed. */
4849
get _afterAllClosed(): Observable<void> {
4950
return this._parentDialog ? this._parentDialog.afterAllClosed : this._afterAllClosedBase;
@@ -124,6 +125,11 @@ export class Dialog {
124125
return dialogRef;
125126
}
126127

128+
ngOnDestroy() {
129+
// Only close all the dialogs at this level.
130+
this._openDialogs.forEach(ref => ref.close());
131+
}
132+
127133
/**
128134
* Forwards emitting events for when dialogs are opened and all dialogs are closed.
129135
*/

0 commit comments

Comments
 (0)