Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dialog): add events (observables) for open & closeAll #2522

Merged
merged 10 commits into from
Jan 26, 2017
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 @@ -67,6 +67,7 @@ import {InputContainerDemo} from './input/input-container-demo';
InputContainerDemo,
JazzDialog,
ContentElementDialog,
IFrameDialog,
ListDemo,
LiveAnnouncerDemo,
MdCheckboxDemoNestedChecklist,
Expand Down Expand Up @@ -102,6 +103,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 @@ -135,6 +135,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 @@ -166,6 +187,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