Skip to content

Commit

Permalink
chore(modals): small refactoring (#2128)
Browse files Browse the repository at this point in the history
  • Loading branch information
valorkin authored and IlyaSurmay committed Jun 26, 2017
1 parent a7605f8 commit 91f06a9
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 77 deletions.
26 changes: 18 additions & 8 deletions src/component-loader/component-loader.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
// todo: merge events onShow, onShown, etc...
// todo: add global positioning configuration?
import {
NgZone, ViewContainerRef, ComponentFactoryResolver, Injector, Renderer,
ElementRef, ComponentRef, ComponentFactory, Type, TemplateRef, EventEmitter,
Provider, ReflectiveInjector
ComponentFactory,
ComponentFactoryResolver,
ComponentRef,
ElementRef,
EventEmitter,
Injector,
NgZone,
Provider,
ReflectiveInjector,
Renderer,
TemplateRef,
Type,
ViewContainerRef
} from '@angular/core';
import { ContentRef } from './content-ref.class';
import { PositioningService, PositioningOptions } from '../positioning';
import { PositioningOptions, PositioningService } from '../positioning';
import { listenToTriggers } from '../utils/triggers';
import { ContentRef } from './content-ref.class';

export interface ListenOptions {
target?: ElementRef;
Expand Down Expand Up @@ -112,7 +122,7 @@ export class ComponentLoader<T> {
return this;
}

public show(opts: {content?: string | TemplateRef<any>, [key:string]: any} = {}): ComponentRef<T> {
public show(opts: { content?: string | TemplateRef<any>, [key: string]: any } = {}): ComponentRef<T> {
this._subscribePositioning();
this._innerComponent = null;

Expand Down Expand Up @@ -191,8 +201,8 @@ export class ComponentLoader<T> {
listenOpts.show = listenOpts.show || (() => this.show());
listenOpts.hide = listenOpts.hide || (() => this.hide());
listenOpts.toggle = listenOpts.toggle || (() => this.isShown
? listenOpts.hide()
: listenOpts.show());
? listenOpts.hide()
: listenOpts.show());

this._unregisterListenersFn = listenToTriggers(
this._renderer,
Expand Down
9 changes: 9 additions & 0 deletions src/modal/bs-modal-factory.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ElementRef, Injectable, Renderer, ViewContainerRef } from '@angular/core';
import { BsModalService } from './bs-modal.service';

@Injectable()
export class BsModalFactory {
constructor(public modalService: BsModalService, private vcRef: ViewContainerRef) {
this.modalService.create(null, this.vcRef, null);
}
}
89 changes: 42 additions & 47 deletions src/modal/bs-modal.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ComponentRef, ElementRef, Injectable, Renderer, TemplateRef, ViewContainerRef } from '@angular/core';

import { ComponentLoader } from '../component-loader/component-loader.class';
import { ModalBackdropComponent } from './modal-backdrop.component';
import { ModalContainerComponent } from './modal-container.component';
import { ComponentLoaderFactory } from '../component-loader/component-loader.factory';
import { Utils } from '../utils/utils.class';
import { ModalBackdropComponent } from './modal-backdrop.component';
import { ModalContainerComponent } from './modal-container.component';
import { BsModalRef, modalConfigDefaults, ModalOptions } from './modal-options.class';

const TRANSITION_DURATION = 300;
Expand All @@ -16,9 +17,10 @@ export class BsModalService {
public config: ModalOptions = modalConfigDefaults;
protected _isShown: boolean = false;
protected timerRmBackDrop: number = 0;
protected backdrop: ComponentRef<ModalBackdropComponent>;
protected backdropRef: ComponentRef<ModalBackdropComponent>;
private _backdrop: ComponentLoader<ModalBackdropComponent>;
private _modal: ComponentLoader<ModalContainerComponent>;

public constructor(private clf: ComponentLoaderFactory) {}

/** Initialization of BsModalService, requires ElementRef, ViewContainerRef and Renderer instances */
Expand All @@ -34,76 +36,69 @@ export class BsModalService {
this.config = Object.assign({}, modalConfigDefaults, config);
clearTimeout(this.timerRmBackDrop);
this._isShown = true;
this.showBackdrop();
this.toggleBackdrop();
const bsModalRef = new BsModalRef();
const modalContainerRef = this._modal
.provide({provide: ModalOptions, useValue: this.config})
.provide({provide: BsModalRef, useValue: bsModalRef})
.attach(ModalContainerComponent)
.show({content});
bsModalRef.hide = () => {modalContainerRef.instance.hide()};
bsModalRef.hide = () => {modalContainerRef.instance.hide();};
bsModalRef.content = this._modal.getInnerComponent() || null;
return bsModalRef;
}

public hide() {
this._isShown = false;
if (this.backdrop && this.backdrop.instance) {
this.backdrop.instance.isShown = false;
if (this.backdropRef && this.backdropRef.instance) {
this.backdropRef.instance.isShown = false;
}
setTimeout(() => {
this.removeBackdrop();
if (this._modal) {
this._modal.hide();
}
this.backdrop = null;
this.backdropRef = null;
}, BACKDROP_TRANSITION_DURATION);
}
/** @internal */
protected showBackdrop(callback?: Function): void {
if (this._isShown && (this.config.backdrop || this.config.backdrop === 'static') && (!this.backdrop || !this.backdrop.instance.isShown)) {
this.removeBackdrop();
this._backdrop
.attach(ModalBackdropComponent)
.to('body')
.show({isAnimated: false});
this.backdrop = this._backdrop._componentRef;

if (this.isAnimated) {
this.backdrop.instance.isAnimated = this.isAnimated;
Utils.reflow(this.backdrop.instance.element.nativeElement);
}

this.backdrop.instance.isShown = true;
if (!callback) {
return;
}
/** @internal */
protected toggleBackdrop(): void {
// this if will not happen
if (!this._isShown && this.backdropRef) {
return this._hideBackdrop();
}

if (!this.isAnimated) {
callback();
return;
}
const isBackdropEnabled = this.config.backdrop || this.config.backdrop === 'static';
const isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
if (this._isShown && isBackdropEnabled && isBackdropInDOM) {
return this._showBackdrop();
}
}

setTimeout(callback, BACKDROP_TRANSITION_DURATION);
} else if (!this._isShown && this.backdrop) {
this.backdrop.instance.isShown = false;
_showBackdrop(): void {
this.removeBackdrop();
this._backdrop
.attach(ModalBackdropComponent)
.to('body')
// .show({isAnimated: false});
.show({isAnimated: this.isAnimated});
this.backdropRef = this._backdrop._componentRef;

let callbackRemove = () => {
this.removeBackdrop();
if (callback) {
callback();
}
};
// if (this.isAnimated) {
// this.backdropRef.instance.isAnimated = this.isAnimated;
// Utils.reflow(this.backdropRef.instance.element.nativeElement);
// }
//
// this.backdropRef.instance.isShown = true;
}

if (this.backdrop.instance.isAnimated) {
this.timerRmBackDrop = setTimeout(callbackRemove, BACKDROP_TRANSITION_DURATION);
} else {
callbackRemove();
}
} else if (callback) {
callback();
}
_hideBackdrop(): void {
this.backdropRef.instance.isShown = false;
const duration = this.backdropRef.instance.isAnimated ? BACKDROP_TRANSITION_DURATION: 0;
this.timerRmBackDrop = setTimeout(() => this.removeBackdrop(), duration);
}

protected removeBackdrop(): void {
this._backdrop.hide();
}
Expand Down
13 changes: 7 additions & 6 deletions src/modal/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export {ModalContainerComponent} from './modal-container.component';
export {ModalBackdropComponent, ModalBackdropOptions} from './modal-backdrop.component';
export {ModalOptions} from './modal-options.class';
export {ModalDirective} from './modal.component';
export {ModalModule} from './modal.module';
export {BsModalService} from './bs-modal.service';
export { ModalContainerComponent } from './modal-container.component';
export { ModalBackdropComponent, ModalBackdropOptions } from './modal-backdrop.component';
export { ModalOptions, BsModalRef } from './modal-options.class';
export { ModalDirective } from './modal.component';
export { ModalModule } from './modal.module';
export { BsModalService } from './bs-modal.service';
export { BsModalFactory } from './bs-modal-factory.service';
37 changes: 23 additions & 14 deletions src/modal/modal-backdrop.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Component, ElementRef, Renderer } from '@angular/core';
import { Component, ElementRef, OnInit, Renderer } from '@angular/core';

import { ClassName } from './modal-options.class';
import { isBs3 } from '../utils/ng2-bootstrap-config';
import { Utils } from '../utils/utils.class';

export class ModalBackdropOptions {
public animate:boolean = true;
public animate: boolean = true;

public constructor(options:ModalBackdropOptions) {
public constructor(options: ModalBackdropOptions) {
Object.assign(this, options);
}
}
Expand All @@ -18,36 +19,44 @@ export class ModalBackdropOptions {
// tslint:disable-next-line
host: {'class': ClassName.BACKDROP}
})
export class ModalBackdropComponent {
public get isAnimated():boolean {
export class ModalBackdropComponent implements OnInit {
public get isAnimated(): boolean {
return this._isAnimated;
}

public set isAnimated(value:boolean) {
public set isAnimated(value: boolean) {
this._isAnimated = value;
this.renderer.setElementClass(this.element.nativeElement, `${ClassName.FADE}`, value);
// this.renderer.setElementClass(this.element.nativeElement, `${ClassName.FADE}`, value);
}

public get isShown():boolean {
public get isShown(): boolean {
return this._isShown;
}

public set isShown(value:boolean) {
public set isShown(value: boolean) {
this._isShown = value;
this.renderer.setElementClass(this.element.nativeElement, `${ClassName.IN}`, value);
if (!isBs3()) {
this.renderer.setElementClass(this.element.nativeElement, `${ClassName.SHOW}`, value);
}
}

public element:ElementRef;
public renderer:Renderer;
public element: ElementRef;
public renderer: Renderer;

protected _isAnimated:boolean;
protected _isShown:boolean = false;
protected _isAnimated: boolean;
protected _isShown = false;

public constructor(element:ElementRef, renderer:Renderer) {
public constructor(element: ElementRef, renderer: Renderer) {
this.element = element;
this.renderer = renderer;
}

ngOnInit(): void {
if (this.isAnimated) {
this.renderer.setElementClass(this.element.nativeElement, `${ClassName.FADE}`, this.isAnimated);
Utils.reflow(this.element.nativeElement);
}
this.isShown = true;
}
}
5 changes: 3 additions & 2 deletions src/modal/modal.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import { PositioningService } from '../positioning';
import { ComponentLoaderFactory } from '../component-loader';
import { ModalContainerComponent } from './modal-container.component';
import { BsModalService } from './bs-modal.service';
import { BsModalFactory } from './bs-modal-factory.service';

@NgModule({
declarations: [ModalBackdropComponent, ModalDirective, ModalContainerComponent],
exports: [ModalBackdropComponent, ModalDirective],
providers: [BsModalService, ComponentLoaderFactory],
// providers: [BsModalService, ComponentLoaderFactory],
entryComponents: [ModalBackdropComponent, ModalContainerComponent]
})
export class ModalModule {
public static forRoot(): ModuleWithProviders {
return {ngModule: ModalModule, providers: [ComponentLoaderFactory, PositioningService]};
return {ngModule: ModalModule, providers: [BsModalFactory, BsModalService, ComponentLoaderFactory, PositioningService]};
}
}

0 comments on commit 91f06a9

Please sign in to comment.