diff --git a/README.md b/README.md
index 02a5bc2..48505fe 100644
--- a/README.md
+++ b/README.md
@@ -101,13 +101,21 @@ Feel free to request more.
#### Outputs
+- `onShow: EventEmitter`
+
+ Emits when the `show.bs.modal` event is triggered, just before the modal is shown. Call `Event.preventDefault()` to cancel the modal from showing.
+
+- `onHide: EventEmitter`
+
+ Emits when the `hide.bs.modal` event is triggered, just before the modal is hidden. Call `BsModalHideEvent.event.preventDefault()` to cancel the modal from hiding.
+
- `onClose: EventEmitter`
Emits when `ModalComponent.close()` is called. Will emit whatever was passed into `ModalComponent.close()`.
-- `onDismiss: EventEmitter`
+- `onDismiss: EventEmitter`
- Emits when `ModalComponent.dismiss()` is called, or when the modal is dismissed with the keyboard or backdrop. Returns a `BsModalCloseSource` that can be used to determine how the modal was dismissed.
+ Emits when `ModalComponent.dismiss()` is called, or when the modal is dismissed with the keyboard or backdrop. Returns a `BsModalHideType` that can be used to determine how the modal was dismissed.
- `onOpen: EventEmitter`
@@ -157,7 +165,7 @@ Feel free to request more.
- `dismissAll(): void`
- Dismiss all open modals.
+ Dismiss all open modals. Inject the `BsModalService` into a componet/service to use.
## Example Usage
diff --git a/src/demo/app/modal-demo.component.html b/src/demo/app/modal-demo.component.html
index ff69e2e..a872d7e 100644
--- a/src/demo/app/modal-demo.component.html
+++ b/src/demo/app/modal-demo.component.html
@@ -18,6 +18,7 @@ Common Usage
Open me!
Large modal
Small modal
+ No Events
@@ -31,11 +32,20 @@ Other Usages
+ Intercepting events
+
+
+ Intercept hide
+ Intercept show
+ | Toggle intercept ({{intercept}})
+
+
+
Output
{{ output }}
-
+
I'm a modal!
@@ -45,12 +55,31 @@ I'm a modal!
{{ item }}
- Selected: {{ selected }}
+ Selected:
+ {{ selected }}
+
-
+
+ I'm a modal!
+
+
+
+ Selected:
+ {{ selected }}
+
+
+
+
+
+
I'm a modal!
@@ -64,13 +93,16 @@ I'm a modal!
-
+
I'm a modal!
- Note: My z-index
is set to 1049
.
+
+ Note: My
+ z-index
is set to
+ 1049
.
Open another modal
@@ -79,7 +111,7 @@ I'm a modal!
-
I'm a stacked modal!
@@ -90,7 +122,7 @@ I'm a stacked modal!
-
+
+
+
+ Can't dismiss if intercept
is enabled
+
+
+
+ Note: Keyboard and backdrop events cannot be prevented with
+ event.preventDefault()
. Use the
+ keyboard
and
+ backdrop
options.
+
+
+ Selected:
+ {{ selected }}
+
+ Toggle intercept ({{intercept}})
+
+
+
+
+
+
+ I'm a modal!
+
+
+
+ Selected:
+ {{ selected }}
+
+
+
+
+
+
diff --git a/src/demo/app/modal-demo.component.ts b/src/demo/app/modal-demo.component.ts
index 1c82c06..4005e09 100644
--- a/src/demo/app/modal-demo.component.ts
+++ b/src/demo/app/modal-demo.component.ts
@@ -1,6 +1,6 @@
-import {Component, ViewChild, ViewEncapsulation} from '@angular/core';
+import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
-import { BsModalComponent, BsModalService } from '../../ng2-bs3-modal/ng2-bs3-modal';
+import { BsModalComponent, BsModalService, BsModalHideType } from '../../ng2-bs3-modal/ng2-bs3-modal';
@Component({
moduleId: module.id,
@@ -36,6 +36,7 @@ export class ModalDemoComponent {
keyboard = true;
backdrop: string | boolean = true;
css = false;
+ intercept = true;
constructor(private router: Router, private modalservice: BsModalService) { }
@@ -43,8 +44,8 @@ export class ModalDemoComponent {
this.output = '(closed) ' + this.selected;
}
- dismissed() {
- this.output = '(dismissed)';
+ dismissed(type) {
+ this.output = `(dismissed) ${BsModalHideType[type]}`;
}
opened() {
@@ -62,6 +63,20 @@ export class ModalDemoComponent {
dismissAll() {
this.modalservice.dismissAll();
}
+
+ interceptDismiss(e) {
+ if (this.intercept && e.type === BsModalHideType.Dismiss) {
+ e.event.preventDefault();
+ this.output = '(intercepted) Dismiss';
+ }
+ }
+
+ interceptOpen(e) {
+ if (this.intercept) {
+ e.preventDefault();
+ this.output = '(intercepted) Open';
+ }
+ }
}
export class Person {
diff --git a/src/ng2-bs3-modal/modal/modal-service.ts b/src/ng2-bs3-modal/modal/modal-service.ts
index d6746f5..b912b9c 100644
--- a/src/ng2-bs3-modal/modal/modal-service.ts
+++ b/src/ng2-bs3-modal/modal/modal-service.ts
@@ -4,39 +4,46 @@ import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/filter';
import { BsModalComponent } from './modal';
-import { BsModalCloseSource } from './models';
+import { BsModalHideType } from './models';
import { JQueryStyleEventEmitter } from 'rxjs/observable/FromEventObservable';
const EVENT_SUFFIX = 'ng2-bs3-modal';
const KEYUP_EVENT_NAME = `keyup.${EVENT_SUFFIX}`;
const CLICK_EVENT_NAME = `click.${EVENT_SUFFIX}`;
+const SHOW_EVENT_NAME = `show.bs.modal.${EVENT_SUFFIX}`;
@Injectable()
export class BsModalService {
private modals: BsModalComponent[] = [];
+ private $body: JQuery;
- public onBackdropClose: Observable;
- public onKeyboardClose: Observable;
+ public onBackdropClose$: Observable;
+ public onKeyboardClose$: Observable;
+ public onModalStack$: Observable;
constructor() {
- this.onBackdropClose = Observable.fromEvent(jQuery(document) as JQueryStyleEventEmitter, CLICK_EVENT_NAME)
- .filter((e: MouseEvent) => e.target === jQuery('.modal')[0])
- .map(() => BsModalCloseSource.Backdrop)
+ this.$body = jQuery(document.body);
+
+ this.onBackdropClose$ = Observable.fromEvent(this.$body as JQueryStyleEventEmitter, CLICK_EVENT_NAME)
+ .filter((e: MouseEvent) => jQuery(e.target).is('.modal'))
+ .map(() => BsModalHideType.Backdrop)
.share();
- this.onKeyboardClose = Observable.fromEvent(jQuery(document) as JQueryStyleEventEmitter, KEYUP_EVENT_NAME)
+ this.onKeyboardClose$ = Observable.fromEvent(this.$body as JQueryStyleEventEmitter, KEYUP_EVENT_NAME)
.filter((e: KeyboardEvent) => e.which === 27)
- .map(() => BsModalCloseSource.Keyboard)
+ .map(() => BsModalHideType.Keyboard)
.share();
- jQuery(document).on('show.bs.modal', '.modal', function () {
- const zIndex = 1040 + (10 * $('.modal:visible').length);
- $(this).css('z-index', zIndex);
- setTimeout(function() {
- $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
- }, 0);
- });
+ this.onModalStack$ = Observable.fromEvent(this.$body as JQueryStyleEventEmitter, SHOW_EVENT_NAME)
+ .do(() => {
+ const zIndex = 1040 + (10 * $('.modal:visible').length);
+ $(this).css('z-index', zIndex);
+ setTimeout(function() {
+ $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
+ }, 0);
+ })
+ .share();
}
public add(modal: BsModalComponent) {
@@ -50,7 +57,10 @@ export class BsModalService {
public focusNext() {
const visible = this.modals.filter(m => m.visible);
- if (visible.length) visible[visible.length - 1].focus();
+ if (visible.length) {
+ this.$body.addClass('modal-open');
+ visible[visible.length - 1].focus();
+ }
}
public dismissAll() {
diff --git a/src/ng2-bs3-modal/modal/modal.ts b/src/ng2-bs3-modal/modal/modal.ts
index 54daeac..f4ac001 100644
--- a/src/ng2-bs3-modal/modal/modal.ts
+++ b/src/ng2-bs3-modal/modal/modal.ts
@@ -1,8 +1,9 @@
import {
Component,
+ OnInit,
+ AfterViewInit,
OnChanges,
OnDestroy,
- AfterViewInit,
Input,
Output,
EventEmitter,
@@ -14,20 +15,23 @@ import {
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Subject } from 'rxjs/Subject';
+import { Subscription } from 'rxjs/Subscription';
import { JQueryStyleEventEmitter } from 'rxjs/observable/FromEventObservable';
+import 'rxjs/add/observable/empty';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/merge';
+import 'rxjs/add/observable/of';
import 'rxjs/add/observable/zip';
import 'rxjs/add/operator/do';
-import 'rxjs/add/operator/first';
+import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/partition';
import 'rxjs/add/operator/share';
+import 'rxjs/add/operator/take';
import 'rxjs/add/operator/toPromise';
+import 'rxjs/add/operator/catch';
-import { BsModalCloseEvent, BsModalCloseSource, BsModalOptions, BsModalSize } from './models';
+import { BsModalHideEvent, BsModalHideType, BsModalOptions, BsModalSize } from './models';
import { BsModalService } from './modal-service';
-import '../utils/to-event-emitter';
const EVENT_SUFFIX = 'ng2-bs3-modal';
const SHOW_EVENT_NAME = `show.bs.modal.${EVENT_SUFFIX}`;
@@ -47,15 +51,22 @@ const DATA_KEY = 'bs.modal';
`
})
-export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
+export class BsModalComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {
private overrideSize: string = null;
private $modal: JQuery;
private $dialog: JQuery;
- private onManualClose: Subject<{}> = new Subject<{}>();
- private onShown: Observable<{}>;
- private onHidden: Observable;
- private onCloseInternal: Observable;
+ private onShowEvent$: Observable;
+ private onShownEvent$: Observable;
+ private onHideEvent$: Observable;
+ private onHiddenEvent$: Observable;
+ private onLoadedEvent$: Observable;
+ private onShown$: Observable<{}>;
+ private onInternalClose$: Subject = new Subject();
+ private onDismiss$: Observable;
+ private onHide$: Observable;
+ private onHidden$: Observable;
+ private subscriptions: Subscription[] = [];
private get options() {
if (!this.$modal) this.init();
return this.$modal.data(DATA_KEY).options;
@@ -69,12 +80,12 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
@Input() public size: string;
@Input() public cssClass: string;
+ @Output() public onShow: EventEmitter = new EventEmitter();
+ @Output() public onOpen: EventEmitter = new EventEmitter();
+ @Output() public onHide: EventEmitter = new EventEmitter();
@Output() public onClose: EventEmitter = new EventEmitter();
- @Output() public onDismiss: EventEmitter;
- @Output() public onOpen: EventEmitter;
- @Output() public onShow: EventEmitter;
- @Output() public onHide: EventEmitter;
- @Output() public onLoaded: EventEmitter;
+ @Output() public onDismiss: EventEmitter = new EventEmitter();
+ @Output() public onLoaded: EventEmitter = new EventEmitter();
@HostBinding('class.fade')
get fadeClass() { return this.animation; }
@@ -93,6 +104,14 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
this.init();
}
+ public ngOnInit() {
+ this.wireUpEventEmitters();
+ }
+
+ public ngAfterViewInit() {
+ this.$dialog = this.$modal.find('.modal-dialog');
+ }
+
public ngOnChanges() {
this.setOptions({
backdrop: this.backdrop,
@@ -101,14 +120,8 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
}
public ngOnDestroy() {
- this.service.remove(this);
- return this.hide().do(() => {
- if (this.$modal) {
- this.$modal.data(DATA_KEY, null);
- this.$modal.remove();
- this.$modal = null;
- }
- }).toPromise();
+ this.onInternalClose$.next(BsModalHideType.Destroy);
+ return this.destroy();
}
public triggerTransitionEnd() {
@@ -119,29 +132,27 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
this.$modal.trigger('focus');
}
- public ngAfterViewInit() {
- this.$dialog = this.$modal.find('.modal-dialog');
- }
-
public routerCanDeactivate(): any {
- return this.ngOnDestroy();
+ this.onInternalClose$.next(BsModalHideType.RouteChange);
+ return this.destroy();
}
public open(size?: string) {
+ this.overrideSize = null;
if (BsModalSize.isValidSize(size)) this.overrideSize = size;
return this.show().toPromise();
}
public close(value?: any): Promise<{}> {
- this.onManualClose.next(BsModalCloseSource.Confirm);
+ this.onInternalClose$.next(BsModalHideType.Close);
return this.hide()
.do(() => this.onClose.emit(value))
.toPromise()
- .then(() => value)
+ .then(() => value);
}
public dismiss(): Promise<{}> {
- this.onManualClose.next(BsModalCloseSource.Dismiss);
+ this.onInternalClose$.next(BsModalHideType.Dismiss);
return this.hide().toPromise();
}
@@ -175,84 +186,103 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
|| this.overrideSize === BsModalSize.Large;
}
- private show(): Observable<{}> {
+ private show(): Observable {
+ if (this.visible) return Observable.of(null);
+
return Observable.create((o: Observer) => {
- if (!this.visible) {
- this.onShown.first().subscribe((next) => {
- o.next(next);
- o.complete();
- });
-
- // Fix for shown.bs.modal not firing when .fade is present
- // https://github.com/twbs/bootstrap/issues/11793
- if (this.animation) {
- this.$dialog.one('transitionend', () => {
- this.$modal.trigger('focus').trigger(SHOWN_EVENT_NAME);
- });
- }
-
- this.$modal.modal('show');
- }
- else {
- o.next(null);
+ this.onShown$.take(1).subscribe(next => {
+ o.next(next);
o.complete();
- }
+ });
+
+ this.transitionFix();
+ this.$modal.modal('show');
});
}
- private hide(): Observable {
- return Observable.create((o: Observer) => {
- if (this.visible) {
- this.onHidden.first().subscribe((next) => {
- o.next(next);
- o.complete();
- });
- this.$modal.modal('hide');
- }
- else {
- o.next(null);
+ private transitionFix() {
+ // Fix for shown.bs.modal not firing when .fade is present
+ // https://github.com/twbs/bootstrap/issues/11793
+ if (this.animation) {
+ this.$dialog.one('transitionend', () => {
+ this.$modal.trigger('focus').trigger(SHOWN_EVENT_NAME);
+ });
+ }
+ }
+
+ private hide(): Observable {
+ if (!this.visible) return Observable.of(null);
+
+ return Observable.create((o: Observer) => {
+ this.onHidden$.take(1).subscribe(next => {
+ o.next(next);
o.complete();
- }
+ });
+
+ this.$modal.modal('hide');
});
}
private init() {
this.$modal = jQuery(this.element.nativeElement);
- this.$modal.appendTo('body');
+ this.$modal.appendTo(document.body);
this.$modal.modal({
show: false
});
- const onHideEvent = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, HIDE_EVENT_NAME);
- const onHiddenEvent = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, HIDDEN_EVENT_NAME);
+ this.onShowEvent$ = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, SHOW_EVENT_NAME);
+ this.onShownEvent$ = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, SHOWN_EVENT_NAME);
+ this.onHideEvent$ = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, HIDE_EVENT_NAME);
+ this.onHiddenEvent$ = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, HIDDEN_EVENT_NAME);
+ this.onLoadedEvent$ = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, LOADED_EVENT_NAME);
- const onClose = Observable
- .merge(this.onManualClose, this.service.onBackdropClose, this.service.onKeyboardClose)
- .share();
+ const onClose$ = Observable
+ .merge(this.onInternalClose$, this.service.onBackdropClose$, this.service.onKeyboardClose$)
+ .filter(() => this.visible);
- this.onHide = Observable.zip(onHideEvent, onClose)
- .map(x => { event: x[0], type: x[1] })
- .toEventEmitter(this.zone);
+ this.onHide$ = Observable.zip(this.onHideEvent$, onClose$)
+ .map(x => { event: x[0], type: x[1] });
- this.onHidden = Observable.zip(onHiddenEvent, onClose)
+ this.onHidden$ = Observable.zip(this.onHiddenEvent$, onClose$)
.map(x => x[1])
.do(this.setVisible(false))
.do(() => this.service.focusNext())
.share();
- this.onShow = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, SHOW_EVENT_NAME)
- .toEventEmitter(this.zone);
-
- this.onShown = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, SHOWN_EVENT_NAME)
+ this.onShown$ = this.onShownEvent$
.do(this.setVisible(true))
.share();
- const [closed, dismissed] = this.onHidden.partition((x) => x === BsModalCloseSource.Confirm);
+ this.onDismiss$ = this.onHidden$
+ .filter((x) => x !== BsModalHideType.Close);
+
+ // Start watching for events
+ this.subscriptions.push(...[
+ this.onShown$.subscribe(() => { }),
+ this.onHidden$.subscribe(() => { }),
+ this.service.onModalStack$.subscribe(() => { })
+ ]);
+ }
+
+ private wireUpEventEmitters() {
- this.onCloseInternal = closed;
- this.onDismiss = dismissed.toEventEmitter(this.zone);
- this.onOpen = this.onShown.toEventEmitter(this.zone);
- this.onLoaded = Observable.fromEvent(this.$modal as JQueryStyleEventEmitter, LOADED_EVENT_NAME).toEventEmitter(this.zone);
+ this.wireUpEventEmitter(this.onShow, this.onShowEvent$);
+ this.wireUpEventEmitter(this.onOpen, this.onShown$);
+ this.wireUpEventEmitter(this.onHide, this.onHide$);
+ this.wireUpEventEmitter(this.onDismiss, this.onDismiss$);
+ this.wireUpEventEmitter(this.onLoaded, this.onLoadedEvent$);
+ }
+
+ private wireUpEventEmitter(emitter: EventEmitter, stream$: Observable) {
+ if (emitter.observers.length === 0) return;
+
+ const sub = stream$.subscribe((next) => {
+ this.zone.run(() => {
+ emitter.next(next);
+ });
+ });
+
+ this.subscriptions.push(sub);
}
private setVisible = (isVisible) => {
@@ -269,4 +299,17 @@ export class BsModalComponent implements OnDestroy, OnChanges, AfterViewInit {
if (options.backdrop !== undefined) this.options.backdrop = backdrop;
if (options.keyboard !== undefined) this.options.keyboard = options.keyboard;
}
+
+ private destroy() {
+ return this.hide().do(() => {
+ this.service.remove(this);
+ this.subscriptions.forEach(s => s.unsubscribe());
+ this.subscriptions = [];
+ if (this.$modal) {
+ this.$modal.data(DATA_KEY, null);
+ this.$modal.remove();
+ this.$modal = null;
+ }
+ }).toPromise();
+ }
}
diff --git a/src/ng2-bs3-modal/modal/models.ts b/src/ng2-bs3-modal/modal/models.ts
index 00b4a8e..1acba59 100644
--- a/src/ng2-bs3-modal/modal/models.ts
+++ b/src/ng2-bs3-modal/modal/models.ts
@@ -1,5 +1,5 @@
-export { BsModalCloseEvent } from './models/modal-close-event';
-export { BsModalCloseSource } from './models/modal-close-source';
+export { BsModalHideEvent } from './models/modal-hide-event';
+export { BsModalHideType } from './models/modal-hide-type';
export { BsModalOptions } from './models/modal-options';
export { BsModalSize } from './models/modal-size';
diff --git a/src/ng2-bs3-modal/modal/models/modal-close-event.ts b/src/ng2-bs3-modal/modal/models/modal-close-event.ts
deleted file mode 100644
index de3adcf..0000000
--- a/src/ng2-bs3-modal/modal/models/modal-close-event.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { BsModalCloseSource } from './modal-close-source';
-
-export interface BsModalCloseEvent {
- event: Event;
- type: BsModalCloseSource;
-}
-
diff --git a/src/ng2-bs3-modal/modal/models/modal-close-source.ts b/src/ng2-bs3-modal/modal/models/modal-close-source.ts
deleted file mode 100644
index 1643266..0000000
--- a/src/ng2-bs3-modal/modal/models/modal-close-source.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export enum BsModalCloseSource {
- Confirm,
- Dismiss,
- Backdrop,
- Keyboard
-}
diff --git a/src/ng2-bs3-modal/modal/models/modal-hide-event.ts b/src/ng2-bs3-modal/modal/models/modal-hide-event.ts
new file mode 100644
index 0000000..e2bbd33
--- /dev/null
+++ b/src/ng2-bs3-modal/modal/models/modal-hide-event.ts
@@ -0,0 +1,7 @@
+import { BsModalHideType } from './modal-hide-type';
+
+export interface BsModalHideEvent {
+ event: Event;
+ type: BsModalHideType;
+}
+
diff --git a/src/ng2-bs3-modal/modal/models/modal-hide-type.ts b/src/ng2-bs3-modal/modal/models/modal-hide-type.ts
new file mode 100644
index 0000000..80d40d8
--- /dev/null
+++ b/src/ng2-bs3-modal/modal/models/modal-hide-type.ts
@@ -0,0 +1,8 @@
+export enum BsModalHideType {
+ Close,
+ Dismiss,
+ Backdrop,
+ Keyboard,
+ RouteChange,
+ Destroy
+}
diff --git a/src/ng2-bs3-modal/ng2-bs3-modal.spec.ts b/src/ng2-bs3-modal/ng2-bs3-modal.spec.ts
index 8c7630d..520836b 100644
--- a/src/ng2-bs3-modal/ng2-bs3-modal.spec.ts
+++ b/src/ng2-bs3-modal/ng2-bs3-modal.spec.ts
@@ -64,6 +64,7 @@ describe('ModalComponent', () => {
modal.onClose.subscribe(spy);
modal.open();
+ tick();
modal.close();
tick();
@@ -86,25 +87,29 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss when modal is dimissed and animation is disabled', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
- const spy = jasmine.createSpy('');
+ const spy = jasmine.createSpy('onDismiss');
+
modal.onDismiss.subscribe(spy);
+ fixture.detectChanges();
+
modal.open();
+ tick();
modal.dismiss();
tick();
+
expect(spy).toHaveBeenCalled();
}));
it('should emit onDismiss when modal is dismissed and animation is enabled', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal: BsModalComponent = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss');
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.detectChanges();
- modal.ngAfterViewInit();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -116,13 +121,13 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss only once', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss').and.callFake(() => { });
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.detectChanges();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -134,14 +139,14 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss only once when showDefaultButtons is false', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss');
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.componentInstance.defaultButtons = false;
fixture.detectChanges();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -153,13 +158,13 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss when modal is closed, opened, then dimissed from backdrop', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss');
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.detectChanges();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -176,13 +181,13 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss when modal is dismissed a second time from backdrop', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss');
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.detectChanges();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -199,14 +204,14 @@ describe('ModalComponent', () => {
}));
it('should emit onDismiss when modal is dismissed a second time from backdrop and showDefaultButtons is false', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onDismiss');
+ modal.onDismiss.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.componentInstance.defaultButtons = false;
fixture.detectChanges();
- modal.onDismiss.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
@@ -223,13 +228,13 @@ describe('ModalComponent', () => {
}));
it('should emit onOpen when modal is opened and animations have been enabled', fakeAsync(() => {
- fixture = createRoot(TestComponent);
+ fixture = createRoot(TestComponent, null, false);
const modal = fixture.componentInstance.modal;
const spy = jasmine.createSpy('onOpenAnimated');
+ modal.onOpen.subscribe(spy);
fixture.componentInstance.animate = true;
fixture.detectChanges();
- modal.onOpen.subscribe(spy);
modal.open();
modal.triggerTransitionEnd();
diff --git a/src/ng2-bs3-modal/utils/to-event-emitter.ts b/src/ng2-bs3-modal/utils/to-event-emitter.ts
deleted file mode 100644
index 13fc05a..0000000
--- a/src/ng2-bs3-modal/utils/to-event-emitter.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Observable } from 'rxjs/Observable';
-import { EventEmitter, NgZone } from '@angular/core';
-
-Observable.prototype.toEventEmitter = toEventEmitter;
-
-export function toEventEmitter(this: Observable, zone: NgZone): EventEmitter {
- const emitter = new EventEmitter(true);
- this.subscribe((next) => {
- zone.run(() => {
- emitter.next(next);
- });
- });
- return emitter;
-}
-
-declare module 'rxjs/Observable' {
- // tslint:disable-next-line:no-shadowed-variable
- interface Observable {
- toEventEmitter: typeof toEventEmitter;
- }
-}
diff --git a/src/test/common.ts b/src/test/common.ts
index 51b5229..67f4e86 100644
--- a/src/test/common.ts
+++ b/src/test/common.ts
@@ -2,9 +2,9 @@ import { Type, } from '@angular/core';
import { Router } from '@angular/router';
import { ComponentFixture, TestBed, tick } from '@angular/core/testing';
-export function createRoot(type: Type, router?: Router): ComponentFixture {
+export function createRoot(type: Type, router?: Router, detect = true): ComponentFixture {
const f = TestBed.createComponent(type);
- f.detectChanges();
+ if (detect) f.detectChanges();
if (router) {
router.initialNavigation();
advance(f);