Skip to content

Commit

Permalink
feat(modal): get all the open modal instances using the NgbModal serv…
Browse files Browse the repository at this point in the history
…ice (#3650)

Fixes #3627
  • Loading branch information
gpolychronis authored and maxokorokov committed Jul 8, 2020
1 parent d11530a commit b45b39a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<button class="btn btn-lg btn-outline-primary" (click)="open()">Launch demo modal</button>
<hr/>
<p>Number of modals: {{modalsNumber}}</p>
8 changes: 7 additions & 1 deletion demo/src/app/components/modal/demos/stacked/modal-stacked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ export class NgbdModal2Content {
templateUrl: './modal-stacked.html'
})
export class NgbdModalStacked {
constructor(private modalService: NgbModal) {}
modalsNumber = 0;

constructor(private modalService: NgbModal) {
this.modalService.activeInstances.subscribe((list) => {
this.modalsNumber = list.length;
});
}

open() {
this.modalService.open(NgbdModal1Content);
Expand Down
6 changes: 6 additions & 0 deletions src/modal/modal-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ApplicationRef,
ComponentFactoryResolver,
ComponentRef,
EventEmitter,
Inject,
Injectable,
Injector,
Expand Down Expand Up @@ -30,6 +31,7 @@ export class NgbModalStack {
private _windowAttributes =
['ariaLabelledBy', 'ariaDescribedBy', 'backdrop', 'centered', 'keyboard', 'scrollable', 'size', 'windowClass'];
private _windowCmpts: ComponentRef<NgbModalWindow>[] = [];
private _activeInstances: EventEmitter<NgbModalRef[]> = new EventEmitter();

constructor(
private _applicationRef: ApplicationRef, private _injector: Injector, @Inject(DOCUMENT) private _document: any,
Expand Down Expand Up @@ -90,6 +92,8 @@ export class NgbModalStack {
return ngbModalRef;
}

get activeInstances() { return this._activeInstances; }

dismissAll(reason?: any) { this._modalRefs.forEach(ngbModalRef => ngbModalRef.dismiss(reason)); }

hasOpenModals(): boolean { return this._modalRefs.length > 0; }
Expand Down Expand Up @@ -204,9 +208,11 @@ export class NgbModalStack {
const index = this._modalRefs.indexOf(ngbModalRef);
if (index > -1) {
this._modalRefs.splice(index, 1);
this._activeInstances.emit(this._modalRefs);
}
};
this._modalRefs.push(ngbModalRef);
this._activeInstances.emit(this._modalRefs);
ngbModalRef.result.then(unregisterModalRef, unregisterModalRef);
}

Expand Down
27 changes: 27 additions & 0 deletions src/modal/modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,32 @@ describe('ngb-modal', () => {
modalInstance1.close();
fixture.detectChanges();
});

it('should iterate over multiple modal instances', async() => {
let n;
const observable = fixture.componentInstance.activeInstances;
observable.subscribe(list => { n = list.length; });
expect(n).toBeUndefined();
fixture.componentInstance.open('foo', {windowClass: 'window-1'});
fixture.detectChanges();
expect(n).toBe(1);

fixture.componentInstance.open('bar', {windowClass: 'window-2'});
fixture.detectChanges();
expect(n).toBe(2);

let windows = document.querySelectorAll('ngb-modal-window');
expect(windows.length).toBe(2);
expect(windows[0]).toHaveCssClass('window-1');
expect(windows[1]).toHaveCssClass('window-2');

fixture.componentInstance.dismissAll();
fixture.detectChanges();
await fixture.whenStable();

expect(fixture.nativeElement).not.toHaveModal();
expect(n).toBe(0);
});
});

describe('vertically centered', () => {
Expand Down Expand Up @@ -952,6 +978,7 @@ class TestComponent {
return this.modalService.open(this.tplContentWithImplicitContext, options);
}
openTplIf(options?: Object) { return this.modalService.open(this.tplContentWithIf, options); }
get activeInstances() { return this.modalService.activeInstances; }
}

@Component({
Expand Down
5 changes: 5 additions & 0 deletions src/modal/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export class NgbModal {
return this._modalStack.open(this._moduleCFR, this._injector, content, combinedOptions);
}

/**
* Returns an observable that holds the active modal instances.
*/
get activeInstances() { return this._modalStack.activeInstances; }

/**
* Dismisses all currently displayed modal windows with the supplied reason.
*
Expand Down

0 comments on commit b45b39a

Please sign in to comment.