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

* 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
This commit is contained in:
Thomas Pink
2017-01-27 00:00:05 +01:00
committed by Andrew Seguin
parent 6d0c40c806
commit 23ab15256f
4 changed files with 110 additions and 3 deletions
+3 -1
View File
@@ -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';
@@ -65,6 +65,7 @@ import {InputContainerDemo} from './input/input-container-demo';
InputContainerDemo,
JazzDialog,
ContentElementDialog,
IFrameDialog,
ListDemo,
LiveAnnouncerDemo,
MdCheckboxDemoNestedChecklist,
@@ -100,6 +101,7 @@ import {InputContainerDemo} from './input/input-container-demo';
DemoApp,
JazzDialog,
ContentElementDialog,
IFrameDialog,
RotiniPanel,
ScienceJoke,
SpagettiPanel,
+52 -2
View File
@@ -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({
@@ -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);
@@ -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
View File
@@ -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'
+26
View File
@@ -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';
@@ -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,
@@ -46,6 +66,7 @@ export class MdDialog {
this._openDialogs.push(dialogRef);
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
this._afterOpen.next(dialogRef);
return dialogRef;
}
@@ -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();
}
}
}
}