Skip to content

Commit bbb1d39

Browse files
crisbetojosephperrott
authored andcommitted
fix(dialog): not closing correctly when detached externally (#11516)
1 parent ef16453 commit bbb1d39

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/lib/dialog/dialog-ref.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,16 @@ export class MatDialogRef<T, R = any> {
6868
_containerInstance._animationStateChanged.pipe(
6969
filter(event => event.phaseName === 'done' && event.toState === 'exit'),
7070
take(1)
71-
)
72-
.subscribe(() => {
73-
this._overlayRef.dispose();
71+
).subscribe(() => this._overlayRef.dispose());
72+
73+
_overlayRef.detachments().subscribe(() => {
74+
this._beforeClose.next(this._result);
75+
this._beforeClose.complete();
7476
this._locationChanges.unsubscribe();
7577
this._afterClosed.next(this._result);
7678
this._afterClosed.complete();
7779
this.componentInstance = null!;
80+
this._overlayRef.dispose();
7881
});
7982

8083
_overlayRef.keydownEvents()

src/lib/dialog/dialog.spec.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {Location} from '@angular/common';
2424
import {SpyLocation} from '@angular/common/testing';
2525
import {Directionality} from '@angular/cdk/bidi';
2626
import {MatDialogContainer} from './dialog-container';
27-
import {OverlayContainer, ScrollStrategy} from '@angular/cdk/overlay';
27+
import {OverlayContainer, ScrollStrategy, ScrollDispatcher, Overlay} from '@angular/cdk/overlay';
2828
import {A, ESCAPE} from '@angular/cdk/keycodes';
2929
import {dispatchKeyboardEvent} from '@angular/cdk/testing';
3030
import {
@@ -34,12 +34,14 @@ import {
3434
MatDialogRef,
3535
MAT_DIALOG_DEFAULT_OPTIONS
3636
} from './index';
37+
import {Subject} from 'rxjs';
3738

3839

3940
describe('MatDialog', () => {
4041
let dialog: MatDialog;
4142
let overlayContainer: OverlayContainer;
4243
let overlayContainerElement: HTMLElement;
44+
let scrolledSubject = new Subject();
4345

4446
let testViewContainerRef: ViewContainerRef;
4547
let viewContainerFixture: ComponentFixture<ComponentWithChildViewContainer>;
@@ -49,7 +51,10 @@ describe('MatDialog', () => {
4951
TestBed.configureTestingModule({
5052
imports: [MatDialogModule, DialogTestModule],
5153
providers: [
52-
{provide: Location, useClass: SpyLocation}
54+
{provide: Location, useClass: SpyLocation},
55+
{provide: ScrollDispatcher, useFactory: () => ({
56+
scrolled: () => scrolledSubject.asObservable()
57+
})},
5358
],
5459
});
5560

@@ -188,6 +193,26 @@ describe('MatDialog', () => {
188193
expect(overlayContainerElement.querySelector('mat-dialog-container')).toBeNull();
189194
}));
190195

196+
it('should dispatch the beforeClose and afterClose events when the ' +
197+
'overlay is detached externally', fakeAsync(inject([Overlay], (overlay: Overlay) => {
198+
const dialogRef = dialog.open(PizzaMsg, {
199+
viewContainerRef: testViewContainerRef,
200+
scrollStrategy: overlay.scrollStrategies.close()
201+
});
202+
const beforeCloseCallback = jasmine.createSpy('beforeClosed callback');
203+
const afterCloseCallback = jasmine.createSpy('afterClosed callback');
204+
205+
dialogRef.beforeClose().subscribe(beforeCloseCallback);
206+
dialogRef.afterClosed().subscribe(afterCloseCallback);
207+
208+
scrolledSubject.next();
209+
viewContainerFixture.detectChanges();
210+
flush();
211+
212+
expect(beforeCloseCallback).toHaveBeenCalledTimes(1);
213+
expect(afterCloseCallback).toHaveBeenCalledTimes(1);
214+
})));
215+
191216
it('should close a dialog and get back a result before it is closed', fakeAsync(() => {
192217
const dialogRef = dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef});
193218

0 commit comments

Comments
 (0)