UNPKG

ngx-bootstrap

Version:
244 lines 10.7 kB
// todo: add delay support // todo: merge events onShow, onShown, etc... // todo: add global positioning configuration? import { ElementRef, EventEmitter, ReflectiveInjector, TemplateRef } from '@angular/core'; import { listenToTriggersV2, registerOutsideClick } from '../utils/triggers'; import { ContentRef } from './content-ref.class'; var ComponentLoader = (function () { /** * Do not use this directly, it should be instanced via * `ComponentLoadFactory.attach` * @internal */ // tslint:disable-next-line function ComponentLoader(_viewContainerRef, _renderer, _elementRef, _injector, _componentFactoryResolver, _ngZone, _applicationRef, _posService) { this._viewContainerRef = _viewContainerRef; this._renderer = _renderer; this._elementRef = _elementRef; this._injector = _injector; this._componentFactoryResolver = _componentFactoryResolver; this._ngZone = _ngZone; this._applicationRef = _applicationRef; this._posService = _posService; this.onBeforeShow = new EventEmitter(); this.onShown = new EventEmitter(); this.onBeforeHide = new EventEmitter(); this.onHidden = new EventEmitter(); this._providers = []; this._isHiding = false; this._listenOpts = {}; this._globalListener = Function.prototype; } Object.defineProperty(ComponentLoader.prototype, "isShown", { get: function () { if (this._isHiding) { return false; } return !!this._componentRef; }, enumerable: true, configurable: true }); ; ComponentLoader.prototype.attach = function (compType) { this._componentFactory = this._componentFactoryResolver .resolveComponentFactory(compType); return this; }; // todo: add behaviour: to target element, `body`, custom element ComponentLoader.prototype.to = function (container) { this.container = container || this.container; return this; }; ComponentLoader.prototype.position = function (opts) { this.attachment = opts.attachment || this.attachment; this._elementRef = opts.target || this._elementRef; return this; }; ComponentLoader.prototype.provide = function (provider) { this._providers.push(provider); return this; }; // todo: appendChild to element or document.querySelector(this.container) ComponentLoader.prototype.show = function (opts) { if (opts === void 0) { opts = {}; } this._subscribePositioning(); this._innerComponent = null; if (!this._componentRef) { this.onBeforeShow.emit(); this._contentRef = this._getContentRef(opts.content); var injector = ReflectiveInjector.resolveAndCreate(this._providers, this._injector); this._componentRef = this._componentFactory.create(injector, this._contentRef.nodes); this._applicationRef.attachView(this._componentRef.hostView); // this._componentRef = this._viewContainerRef // .createComponent(this._componentFactory, 0, injector, this._contentRef.nodes); this.instance = this._componentRef.instance; Object.assign(this._componentRef.instance, opts); if (this.container instanceof ElementRef) { this.container.nativeElement .appendChild(this._componentRef.location.nativeElement); } if (this.container === 'body' && typeof document !== 'undefined') { document.querySelector(this.container) .appendChild(this._componentRef.location.nativeElement); } if (!this.container && this._elementRef && this._elementRef.nativeElement.parentElement) { this._elementRef.nativeElement.parentElement .appendChild(this._componentRef.location.nativeElement); } // we need to manually invoke change detection since events registered // via // Renderer::listen() are not picked up by change detection with the // OnPush strategy if (this._contentRef.componentRef) { this._innerComponent = this._contentRef.componentRef.instance; this._contentRef.componentRef.changeDetectorRef.markForCheck(); this._contentRef.componentRef.changeDetectorRef.detectChanges(); } this._componentRef.changeDetectorRef.markForCheck(); this._componentRef.changeDetectorRef.detectChanges(); this.onShown.emit(this._componentRef.instance); } this._registerOutsideClick(); return this._componentRef; }; ComponentLoader.prototype.hide = function () { if (!this._componentRef) { return this; } this.onBeforeHide.emit(this._componentRef.instance); var componentEl = this._componentRef.location.nativeElement; componentEl.parentNode.removeChild(componentEl); if (this._contentRef.componentRef) { this._contentRef.componentRef.destroy(); } this._componentRef.destroy(); if (this._viewContainerRef && this._contentRef.viewRef) { this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._contentRef.viewRef)); } // this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._componentRef.hostView)); // // if (this._contentRef.viewRef && this._viewContainerRef.indexOf(this._contentRef.viewRef) !== -1) { // this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._contentRef.viewRef)); // } this._contentRef = null; this._componentRef = null; this._removeGlobalListener(); this.onHidden.emit(); return this; }; ComponentLoader.prototype.toggle = function () { if (this.isShown) { this.hide(); return; } this.show(); }; ComponentLoader.prototype.dispose = function () { if (this.isShown) { this.hide(); } this._unsubscribePositioning(); if (this._unregisterListenersFn) { this._unregisterListenersFn(); } }; ComponentLoader.prototype.listen = function (listenOpts) { var _this = this; this.triggers = listenOpts.triggers || this.triggers; this._listenOpts.outsideClick = listenOpts.outsideClick; listenOpts.target = listenOpts.target || this._elementRef.nativeElement; var hide = this._listenOpts.hide = function () { return listenOpts.hide ? listenOpts.hide() : _this.hide(); }; var show = this._listenOpts.show = function (registerHide) { listenOpts.show ? listenOpts.show(registerHide) : _this.show(registerHide); registerHide(); }; var toggle = function (registerHide) { _this.isShown ? hide() : show(registerHide); }; this._unregisterListenersFn = listenToTriggersV2(this._renderer, { target: listenOpts.target, triggers: listenOpts.triggers, show: show, hide: hide, toggle: toggle }); return this; }; ComponentLoader.prototype._removeGlobalListener = function () { if (this._globalListener) { this._globalListener(); this._globalListener = null; } }; ComponentLoader.prototype.attachInline = function (vRef, template) { this._inlineViewRef = vRef.createEmbeddedView(template); return this; }; ComponentLoader.prototype._registerOutsideClick = function () { var _this = this; if (!this._componentRef || !this._componentRef.location) { return; } // why: should run after first event bubble var target = this._componentRef.location.nativeElement; setTimeout(function () { _this._globalListener = registerOutsideClick(_this._renderer, { targets: [target, _this._elementRef.nativeElement], outsideClick: _this._listenOpts.outsideClick, hide: function () { return _this._listenOpts.hide(); } }); }); }; ComponentLoader.prototype.getInnerComponent = function () { return this._innerComponent; }; ComponentLoader.prototype._subscribePositioning = function () { var _this = this; if (this._zoneSubscription || !this.attachment) { return; } this._zoneSubscription = this._ngZone .onStable.subscribe(function () { if (!_this._componentRef) { return; } _this._posService.position({ element: _this._componentRef.location, target: _this._elementRef, attachment: _this.attachment, appendToBody: _this.container === 'body' }); }); }; ComponentLoader.prototype._unsubscribePositioning = function () { if (!this._zoneSubscription) { return; } this._zoneSubscription.unsubscribe(); this._zoneSubscription = null; }; ComponentLoader.prototype._getContentRef = function (content) { if (!content) { return new ContentRef([]); } if (content instanceof TemplateRef) { if (this._viewContainerRef) { var viewRef_1 = this._viewContainerRef.createEmbeddedView(content); return new ContentRef([viewRef_1.rootNodes], viewRef_1); } var viewRef = content.createEmbeddedView({}); this._applicationRef.attachView(viewRef); return new ContentRef([viewRef.rootNodes], viewRef); } if (typeof content === 'function') { var contentCmptFactory = this._componentFactoryResolver.resolveComponentFactory(content); var modalContentInjector = ReflectiveInjector.resolveAndCreate(this._providers.concat([content]), this._injector); var componentRef = contentCmptFactory.create(modalContentInjector); this._applicationRef.attachView(componentRef.hostView); return new ContentRef([[componentRef.location.nativeElement]], componentRef.hostView, componentRef); } return new ContentRef([[this._renderer.createText(null, "" + content)]]); }; return ComponentLoader; }()); export { ComponentLoader }; //# sourceMappingURL=component-loader.class.js.map