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; }); } 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..11a8bdb48fd4 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -140,6 +140,25 @@ describe('MdDialog', () => { }); })); + it('should close a dialog and get back a result before it is closed', async(() => { + 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(beforeCloseHandler); + dialogRef.close('Bulbasaurus'); + viewContainerFixture.detectChanges(); + + viewContainerFixture.whenStable().then(() => { + expect(beforeCloseHandler).toHaveBeenCalledWith('Bulbasaurus'); + expect(overlayContainerElement.querySelector('md-dialog-container')).toBeNull(); + }); + })); + it('should close a dialog via the escape key', async(() => { dialog.open(PizzaMsg, { viewContainerRef: testViewContainerRef