Skip to content

Commit 6d21a28

Browse files
committed
feat(dialog): add the ability to close all dialogs
Adds a `closeAll` method that closes all of the currently-open dialogs.
1 parent 26eb7ce commit 6d21a28

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

src/lib/dialog/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ MdDialog is a service, which opens dialogs components in the view.
77
| Name | Description |
88
| --- | --- |
99
| `open(component: ComponentType<T>, config: MdDialogConfig): MdDialogRef<T>` | Creates and opens a dialog matching material spec. |
10+
| `closeAll(): void` | Closes all of the dialogs that are currently open. |
1011

1112
### Config
1213

src/lib/dialog/dialog.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,18 @@ describe('MdDialog', () => {
214214
expect(overlayPane.style.right).toBe('125px');
215215
});
216216

217+
it('should close all of the dialogs', () => {
218+
dialog.open(PizzaMsg);
219+
dialog.open(PizzaMsg);
220+
dialog.open(PizzaMsg);
221+
222+
expect(overlayContainerElement.querySelectorAll('md-dialog-container').length).toBe(3);
223+
224+
dialog.closeAll();
225+
226+
expect(overlayContainerElement.querySelectorAll('md-dialog-container').length).toBe(0);
227+
});
228+
217229
describe('disableClose option', () => {
218230
it('should prevent closing via clicks on the backdrop', () => {
219231
dialog.open(PizzaMsg, {

src/lib/dialog/dialog.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export {MdDialogRef} from './dialog-ref';
2020

2121

2222
// TODO(jelbourn): add support for opening with a TemplateRef
23-
// TODO(jelbourn): add `closeAll` method
2423
// TODO(jelbourn): dialog content directives (e.g., md-dialog-header)
2524
// TODO(jelbourn): animations
2625

@@ -31,6 +30,9 @@ export {MdDialogRef} from './dialog-ref';
3130
*/
3231
@Injectable()
3332
export class MdDialog {
33+
/** Keeps track of the currently-open dialogs. */
34+
private _openDialogs: MdDialogRef<any>[] = [];
35+
3436
constructor(private _overlay: Overlay, private _injector: Injector) { }
3537

3638
/**
@@ -43,8 +45,27 @@ export class MdDialog {
4345

4446
let overlayRef = this._createOverlay(config);
4547
let dialogContainer = this._attachDialogContainer(overlayRef, config);
48+
let dialogRef = this._attachDialogContent(component, dialogContainer, overlayRef);
49+
50+
this._openDialogs.push(dialogRef);
51+
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
4652

47-
return this._attachDialogContent(component, dialogContainer, overlayRef);
53+
return dialogRef;
54+
}
55+
56+
/**
57+
* Closes all of the currently-open dialogs.
58+
*/
59+
closeAll(): void {
60+
let i = this._openDialogs.length;
61+
62+
while (i--) {
63+
// The `_openDialogs` property isn't updated after close until the rxjs subscription
64+
// runs on the next microtask, in addition to modifying the array as we're going
65+
// through it. We loop through all of them and call close without assuming that
66+
// they'll be removed from the list instantaneously.
67+
this._openDialogs[i].close();
68+
}
4869
}
4970

5071
/**
@@ -138,6 +159,17 @@ export class MdDialog {
138159

139160
return state;
140161
}
162+
163+
/**
164+
* Removes a dialog from the array of open dialogs.
165+
*/
166+
private _removeOpenDialog(dialogRef: MdDialogRef<any>) {
167+
let index = this._openDialogs.indexOf(dialogRef);
168+
169+
if (index > -1) {
170+
this._openDialogs.splice(index, 1);
171+
}
172+
}
141173
}
142174

143175
/**

0 commit comments

Comments
 (0)