From 7b734619290c3d0610fa05387b45ddbd5175356f Mon Sep 17 00:00:00 2001 From: "Shlomi Assaf (shlassaf)" Date: Sun, 21 Aug 2016 21:42:07 +0300 Subject: [PATCH] fix(bootstrap): modal wont animate when closing via clicking outside of modal bounds fix(vex): modal wont animate on close/dismiss --- .../overlay/overlay.component.ts | 18 ++++++++++++++++++ .../angular2-modal/overlay/overlay.service.ts | 2 +- .../angular2-modal/plugins/bootstrap/modal.ts | 8 ++++++++ .../angular2-modal/plugins/vex/modal.ts | 9 +++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/components/angular2-modal/overlay/overlay.component.ts b/src/components/angular2-modal/overlay/overlay.component.ts index 2793d93f..e3ef90c3 100644 --- a/src/components/angular2-modal/overlay/overlay.component.ts +++ b/src/components/angular2-modal/overlay/overlay.component.ts @@ -1,6 +1,7 @@ declare const clearTimeout: any; import { + ApplicationRef, Component, ComponentRef, ElementRef, @@ -35,12 +36,29 @@ export class ModalOverlay extends BaseDynamicComponent { @ViewChild('vcRef', {read: ViewContainerRef}) private vcRef: ViewContainerRef; constructor(private dialogRef: DialogRef, + private appRef: ApplicationRef, el: ElementRef, sanitizer: DomSanitizationService) { super(sanitizer, el); this.activateAnimationListener(); } + /** + * Performs an ApplicationRef.tick + * + */ + tick(): void { + // this.cdr.markForCheck(); + // this.cdr.detectChanges(); + this.appRef.tick(); + + // TODO: + // Change detection doesn't run after doing some operations in plugins. + // this function is a workaround for those situations. (see bootstrap/vex modal implementations) + // strange enough, only ApplicationRef.tick() works, the CDR does not... probably due to + // the need to trigger from a higher change detector, needs investigation. + } + addComponent(type: any, bindings?: ResolvedReflectiveProvider[]): ComponentRef { return super._addComponent(type, this.vcRef, bindings); } diff --git a/src/components/angular2-modal/overlay/overlay.service.ts b/src/components/angular2-modal/overlay/overlay.service.ts index 520c7525..ecffe5b2 100644 --- a/src/components/angular2-modal/overlay/overlay.service.ts +++ b/src/components/angular2-modal/overlay/overlay.service.ts @@ -9,7 +9,7 @@ import { OverlayContext } from '../models/overlay-context'; const _stack = new DialogRefStack(); @Injectable() -export abstract class Overlay { +export class Overlay { /** * A Default view container ref, usually the app root container ref. * Make sure not to provide something that might get destroyed, it will destroy the modals too. diff --git a/src/components/angular2-modal/plugins/bootstrap/modal.ts b/src/components/angular2-modal/plugins/bootstrap/modal.ts index 24a239a9..00756a0c 100644 --- a/src/components/angular2-modal/plugins/bootstrap/modal.ts +++ b/src/components/angular2-modal/plugins/bootstrap/modal.ts @@ -81,6 +81,14 @@ export class Modal extends Modal_ { backdrop.removeClass('in'); container.removeClass('in'); + // TODO: + // Change detection doesn't run after removing these classes, not even in 'nextTurn' + // e.g: backdrop.removeClass('in', true); + // the only solution is to change immediately and tick the change detection. + // this only happen when clicking outside of the bounds (overlayDialogBoundary). + // oddly using ChangeDetectorRef.detectChanges() doesn't work... ??? + // running inside zone didn't help. + overlay.tick(); backdrop.animationEnd$.first().subscribe(type => completer.resolve()); diff --git a/src/components/angular2-modal/plugins/vex/modal.ts b/src/components/angular2-modal/plugins/vex/modal.ts index 2038cffd..2ce7cafe 100644 --- a/src/components/angular2-modal/plugins/vex/modal.ts +++ b/src/components/angular2-modal/plugins/vex/modal.ts @@ -77,6 +77,15 @@ export class Modal extends Modal_ { overlay.beforeDestroy(() => { overlay.addClass('vex-closing'); + // TODO: + // Change detection doesn't run after removing these classes, not even in 'nextTurn' + // e.g: backdrop.removeClass('in', true); + // the only solution is to change immediately and tick the change detection. + // This happen for every click (unlike bootstrap plugin). + // oddly using ChangeDetectorRef.detectChanges() doesn't work... ??? + // running inside zone didn't help. + overlay.tick(); + const completer = new PromiseCompleter(); container.animationEnd$.first().subscribe(type => completer.resolve()); return completer.promise;