Skip to content

Commit

Permalink
feat(dialog): add events (observables) for open & closeAll (#2522)
Browse files Browse the repository at this point in the history
* added afterOpen & afterAllClosed observables to NgDialog + tests + demo

* typo

* fixed demo for aot

* removed unused src argument in dialog demo

* added viewContainerRef to dialog open tests

* reworked dialog closeAll & open events based on feedback

* added comment to change commit to the right username

* added types for afterOpen & afterAllClosed

* _afterAllClosed and _afterOpen subjects now delegate to state of parentDialog  & removed spaces from inside import braces

* fixed tslint error in dialog.ts
  • Loading branch information
thomaspink authored and andrewseguin committed Jan 26, 2017
1 parent 6d0c40c commit 23ab152
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/demo-app/demo-app-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {MaterialModule, OverlayContainer,
FullscreenOverlayContainer} from '@angular/material';
import {DEMO_APP_ROUTES} from './demo-app/routes';
import {ProgressBarDemo} from './progress-bar/progress-bar-demo';
import {JazzDialog, ContentElementDialog, DialogDemo} from './dialog/dialog-demo';
import {JazzDialog, ContentElementDialog, DialogDemo, IFrameDialog} from './dialog/dialog-demo';
import {RippleDemo} from './ripple/ripple-demo';
import {IconDemo} from './icon/icon-demo';
import {GesturesDemo} from './gestures/gestures-demo';
Expand Down Expand Up @@ -65,6 +65,7 @@ import {InputContainerDemo} from './input/input-container-demo';
InputContainerDemo,
JazzDialog,
ContentElementDialog,
IFrameDialog,
ListDemo,
LiveAnnouncerDemo,
MdCheckboxDemoNestedChecklist,
Expand Down Expand Up @@ -100,6 +101,7 @@ import {InputContainerDemo} from './input/input-container-demo';
DemoApp,
JazzDialog,
ContentElementDialog,
IFrameDialog,
RotiniPanel,
ScienceJoke,
SpagettiPanel,
Expand Down
54 changes: 52 additions & 2 deletions src/demo-app/dialog/dialog-demo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Component} from '@angular/core';
import {Component, Inject} from '@angular/core';
import {DOCUMENT} from '@angular/platform-browser';
import {MdDialog, MdDialogRef, MdDialogConfig} from '@angular/material';

@Component({
Expand All @@ -23,7 +24,19 @@ export class DialogDemo {
}
};

constructor(public dialog: MdDialog) { }
constructor(public dialog: MdDialog, @Inject(DOCUMENT) doc: any) {
// Possible useful example for the open and closeAll events.
// Adding a class to the body if a dialog opens and
// removing it after all open dialogs are closed
dialog.afterOpen.subscribe((ref: MdDialogRef<any>) => {
if (!doc.body.classList.contains('no-scroll')) {
doc.body.classList.add('no-scroll');
}
});
dialog.afterAllClosed.subscribe(() => {
doc.body.classList.remove('no-scroll');
});
}

openJazz() {
this.dialogRef = this.dialog.open(JazzDialog, this.config);
Expand Down Expand Up @@ -91,9 +104,46 @@ export class JazzDialog {
color="primary"
href="https://en.wikipedia.org/wiki/Neptune"
target="_blank">Read more on Wikipedia</a>
<button
md-button
color="secondary"
(click)="showInStackedDialog()">
Show in Dialog</button>
</md-dialog-actions>
`
})
export class ContentElementDialog {
actionsAlignment: string;

constructor(public dialog: MdDialog) { }

showInStackedDialog() {
this.dialog.open(IFrameDialog);
}
}

@Component({
selector: 'demo-iframe-dialog',
styles: [
`iframe {
width: 800px;
}`
],
template: `
<h2 md-dialog-title>Neptune</h2>
<md-dialog-content>
<iframe frameborder="0" src="https://en.wikipedia.org/wiki/Neptune"></iframe>
</md-dialog-content>
<md-dialog-actions>
<button
md-raised-button
color="primary"
md-dialog-close>Close</button>
</md-dialog-actions>
`
})
export class IFrameDialog {
}
29 changes: 29 additions & 0 deletions src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,35 @@ describe('MdDialog', () => {
expect(overlayContainerElement.querySelector('md-dialog-container')).toBeFalsy();
});

it('should notify the observers if a dialog has been opened', () => {
let ref: MdDialogRef<PizzaMsg>;
dialog.afterOpen.subscribe(r => {
ref = r;
});
expect(dialog.open(PizzaMsg, {
viewContainerRef: testViewContainerRef
})).toBe(ref);
});

it('should notify the observers if all open dialogs have finished closing', () => {
const ref1 = dialog.open(PizzaMsg, {
viewContainerRef: testViewContainerRef
});
const ref2 = dialog.open(ContentElementDialog, {
viewContainerRef: testViewContainerRef
});
let allClosed = false;

dialog.afterAllClosed.subscribe(() => {
allClosed = true;
});

ref1.close();
expect(allClosed).toBeFalsy();
ref2.close();
expect(allClosed).toBeTruthy();
});

it('should should override the width of the overlay pane', () => {
dialog.open(PizzaMsg, {
width: '500px'
Expand Down
26 changes: 26 additions & 0 deletions src/lib/dialog/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {Injector, ComponentRef, Injectable, Optional, SkipSelf} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';

import {Overlay, OverlayRef, ComponentType, OverlayState, ComponentPortal} from '../core';
import {extendObject} from '../core/util/object-extend';
Expand All @@ -20,12 +22,30 @@ import {MdDialogContainer} from './dialog-container';
@Injectable()
export class MdDialog {
private _openDialogsAtThisLevel: MdDialogRef<any>[] = [];
private _afterAllClosedAtThisLevel = new Subject<void>();
private _afterOpenAtThisLevel = new Subject<MdDialogRef<any>>();

/** Keeps track of the currently-open dialogs. */
get _openDialogs(): MdDialogRef<any>[] {
return this._parentDialog ? this._parentDialog._openDialogs : this._openDialogsAtThisLevel;
}

/** Subject for notifying the user that all open dialogs have finished closing. */
get _afterOpen(): Subject<MdDialogRef<any>> {
return this._parentDialog ? this._parentDialog._afterOpen : this._afterOpenAtThisLevel;
}
/** Subject for notifying the user that a dialog has opened. */
get _afterAllClosed(): Subject<void> {
return this._parentDialog ?
this._parentDialog._afterAllClosed : this._afterAllClosedAtThisLevel;
}

/** Gets an observable that is notified when a dialog has been opened. */
afterOpen: Observable<MdDialogRef<any>> = this._afterOpen.asObservable();

/** Gets an observable that is notified when all open dialog have finished closing. */
afterAllClosed: Observable<void> = this._afterAllClosed.asObservable();

constructor(
private _overlay: Overlay,
private _injector: Injector,
Expand All @@ -46,6 +66,7 @@ export class MdDialog {

this._openDialogs.push(dialogRef);
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
this._afterOpen.next(dialogRef);

return dialogRef;
}
Expand Down Expand Up @@ -169,6 +190,11 @@ export class MdDialog {

if (index > -1) {
this._openDialogs.splice(index, 1);

// no open dialogs are left, call next on afterAllClosed Subject
if (!this._openDialogs.length) {
this._afterAllClosed.next();
}
}
}
}
Expand Down

0 comments on commit 23ab152

Please sign in to comment.