From 25a8b1b729e7a5db3c9fe0cd4801869b43cf7a4b Mon Sep 17 00:00:00 2001 From: Will Howell Date: Wed, 9 Aug 2017 11:37:36 -0400 Subject: [PATCH 1/4] feat(dialog): add beforeClose method --- src/lib/dialog/dialog-ref.ts | 18 ++++++++++++++++-- src/lib/dialog/dialog.spec.ts | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/lib/dialog/dialog-ref.ts b/src/lib/dialog/dialog-ref.ts index 5b5a52169311..f0dc22271957 100644 --- a/src/lib/dialog/dialog-ref.ts +++ b/src/lib/dialog/dialog-ref.ts @@ -15,7 +15,7 @@ import {MdDialogContainer} from './dialog-container'; // TODO(jelbourn): resizing -// TODO(jelbourn): afterOpen and beforeClose +// TODO(jelbourn): afterOpen // Counter for unique dialog ids. let uniqueId = 0; @@ -33,6 +33,9 @@ export class MdDialogRef { /** Subject for notifying the user that the dialog has finished closing. */ private _afterClosed: Subject = new Subject(); + /** Subject for notifying the user that the dialog has started closing. */ + private _beforeClose: Subject = new Subject(); + /** Result to be passed to afterClosed. */ private _result: any; @@ -63,7 +66,11 @@ export class MdDialogRef { RxChain.from(this._containerInstance._animationStateChanged) .call(filter, event => event.phaseName === 'start') .call(first) - .subscribe(() => this._overlayRef.detachBackdrop()); + .subscribe(() => { + this._beforeClose.next(dialogResult); + this._beforeClose.complete(); + this._overlayRef.detachBackdrop(); + }); this._containerInstance._startExitAnimation(); } @@ -75,6 +82,13 @@ export class MdDialogRef { return this._afterClosed.asObservable(); } + /** + * Gets an observable that is notified when the dialog has started closing. + */ + beforeClose(): Observable { + return this._beforeClose.asObservable(); + } + /** * Updates the dialog's position. * @param position New dialog position. diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 398fd269caa1..ccc7368fb777 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -140,6 +140,20 @@ describe('MdDialog', () => { }); })); + it('should close a dialog and get back a result before it is closed', async(() => { + let dialogRef = dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef }); + let beforeCloseCallback = jasmine.createSpy('beforeClose callback'); + + dialogRef.beforeClose().subscribe(beforeCloseCallback); + dialogRef.close('Bulbasaurus'); + viewContainerFixture.detectChanges(); + + viewContainerFixture.whenStable().then(() => { + expect(beforeCloseCallback).toHaveBeenCalledWith('Bulbasaurus'); + expect(overlayContainerElement.querySelector('md-dialog-container')).toBeNull(); + }); + })); + it('should close a dialog via the escape key', async(() => { dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef From 39e38da1a7065e6227e8eea37722d58e90ff4631 Mon Sep 17 00:00:00 2001 From: Will Howell Date: Wed, 9 Aug 2017 11:50:17 -0400 Subject: [PATCH 2/4] Add beforeClose feature to dialog demo --- src/demo-app/dialog/dialog-demo.html | 3 ++- src/demo-app/dialog/dialog-demo.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/demo-app/dialog/dialog-demo.html b/src/demo-app/dialog/dialog-demo.html index 330424f682c4..2a335be3841e 100644 --- a/src/demo-app/dialog/dialog-demo.html +++ b/src/demo-app/dialog/dialog-demo.html @@ -75,7 +75,8 @@

Other options

-

Last close result: {{lastCloseResult}}

+

Last afterClosed result: {{lastAfterClosedResult}}

+

Last beforeClose result: {{lastBeforeCloseResult}}

I'm a template dialog. I've been opened {{numTemplateOpens}} times! diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts index 44573b8e0147..339fcbffa018 100644 --- a/src/demo-app/dialog/dialog-demo.ts +++ b/src/demo-app/dialog/dialog-demo.ts @@ -11,7 +11,8 @@ import {MdDialog, MdDialogRef, MD_DIALOG_DATA} from '@angular/material'; }) export class DialogDemo { dialogRef: MdDialogRef | null; - lastCloseResult: string; + lastAfterClosedResult: string; + lastBeforeCloseResult: string; actionsAlignment: string; config = { disableClose: false, @@ -51,8 +52,11 @@ export class DialogDemo { openJazz() { this.dialogRef = this.dialog.open(JazzDialog, this.config); + this.dialogRef.beforeClose().subscribe((result: string) => { + this.lastBeforeCloseResult = result; + }); this.dialogRef.afterClosed().subscribe((result: string) => { - this.lastCloseResult = result; + this.lastAfterClosedResult = result; this.dialogRef = null; }); } From c262622b756044c5a205eb0a128c78c941a9b5ba Mon Sep 17 00:00:00 2001 From: Will Howell Date: Wed, 16 Aug 2017 17:11:42 -0400 Subject: [PATCH 3/4] test that beforeClose emits before container is destroyed --- src/lib/dialog/dialog.spec.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index ccc7368fb777..5bbcea4974ea 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -141,15 +141,20 @@ describe('MdDialog', () => { })); it('should close a dialog and get back a result before it is closed', async(() => { - let dialogRef = dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef }); - let beforeCloseCallback = jasmine.createSpy('beforeClose callback'); + const dialogRef = dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef }); + + // beforeClose should emit before dialog container is destroyed + const beforeCloseHandler = jasmine.createSpy('beforeClose callback').and.callFake(() => { + expect(overlayContainerElement.querySelector('md-dialog-container')) + .not.toBeNull('dialog container exists when beforeClose is called'); + }); - dialogRef.beforeClose().subscribe(beforeCloseCallback); + dialogRef.beforeClose().subscribe(beforeCloseHandler); dialogRef.close('Bulbasaurus'); viewContainerFixture.detectChanges(); viewContainerFixture.whenStable().then(() => { - expect(beforeCloseCallback).toHaveBeenCalledWith('Bulbasaurus'); + expect(beforeCloseHandler).toHaveBeenCalledWith('Bulbasaurus'); expect(overlayContainerElement.querySelector('md-dialog-container')).toBeNull(); }); })); From 93043317297780b5c16ac0b8309cef74a01022c9 Mon Sep 17 00:00:00 2001 From: Will Howell Date: Thu, 17 Aug 2017 12:15:16 -0400 Subject: [PATCH 4/4] Address comment --- src/lib/dialog/dialog.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 5bbcea4974ea..11a8bdb48fd4 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -141,7 +141,7 @@ describe('MdDialog', () => { })); it('should close a dialog and get back a result before it is closed', async(() => { - const dialogRef = dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef }); + const dialogRef = dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef}); // beforeClose should emit before dialog container is destroyed const beforeCloseHandler = jasmine.createSpy('beforeClose callback').and.callFake(() => {