UNPKG

ng-ytl-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

263 lines (240 loc) 7.74 kB
/* tslint:disable:prefer-method-signature no-string-literal */ import { ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, Injectable, ModuleWithComponentFactories, TemplateRef, Type, } from '@angular/core'; import { NzLocaleService } from '../locale/index'; import { NzConfirmComponent } from './nz-confirm.component'; import { BaseOptions, ConfirmOptions, ModalOptions } from './nz-modal-options.provider'; import { NzModalSubject } from './nz-modal-subject.service'; import { NzModalComponent } from './nz-modal.component'; export interface ConfigInterface { type?: string; title?: string; /* tslint:disable-next-line:no-any */ content?: string | Type<any>; width?: string | number; zIndex?: number; iconType?: string; okText?: string; nzClass?: string; cancelText?: string; style?: object; class?: string; closable?: boolean; maskClosable?: boolean; wrapClassName?: string; footer?: TemplateRef<void> | boolean; showConfirmLoading?: boolean; onOk?: () => void; onCancel?: () => void; componentParams?: object; moduleWithComponentFactories?: ModuleWithComponentFactories<void>; } @Injectable() export class NzModalService { _modalCompFactory: ComponentFactory<NzModalComponent>; _confirmCompFactory: ComponentFactory<NzConfirmComponent>; constructor(private _appRef: ApplicationRef, private _cfr: ComponentFactoryResolver, private _locale: NzLocaleService) { this._modalCompFactory = this._cfr.resolveComponentFactory(NzModalComponent); this._confirmCompFactory = this._cfr.resolveComponentFactory(NzConfirmComponent); } // TODO: add type checking for this method /* tslint:disable-next-line:no-any */ _initConfig(initialConfig: ConfigInterface, options: BaseOptions = {} as any): any { const props = {}; const optionalParams: string[] = [ 'componentParams', // 将componentParams放在第一位是因为必须在content赋值前进行赋值 'visible', 'title', 'content', 'footer', 'width', 'zIndex', 'okText', 'cancelText', 'style', 'class', 'onOk', 'onCancel', 'closable', 'maskClosable', 'wrapClassName', 'iconType', 'confirmType', 'moduleWithComponentFactories' ]; const config = { ...options, ...initialConfig }; optionalParams.forEach(key => { if (config[ key ] !== undefined) { const modalKey = 'nz' + key.replace(/^\w{1}/, (a) => { return a.toLocaleUpperCase(); }); props[ modalKey ] = config[ key ]; } }); const isShowConfirmLoading = !!config[ 'showConfirmLoading' ]; props[ 'onOk' ] = this._getConfirmCb(props[ 'nzOnOk' ], isShowConfirmLoading); props[ 'onCancel' ] = this._getConfirmCb(props[ 'nzOnCancel' ]); // 在service模式下,不需要nzOnOk,防止触发this.nzOnOk.emit(e); delete props[ 'nzOnOk' ]; delete props[ 'nzOnCancel' ]; return props; } // TODO: add type checking for this method /* tslint:disable-next-line:no-any */ _getConfirmCb(fn?: () => Promise<void> | void, isShowConfirmLoading: boolean = false): any { return (_close, _instance) => { if (isShowConfirmLoading) { _instance.nzConfirmLoading = true; } if (fn) { const ret = fn(); if (!ret) { _close(); } else if (ret.then) { ret.then(_close); } } else { _close(); } }; } // TODO: add base class or shared interface for those two component _open(props: ConfigInterface, factory: ComponentFactory<NzModalComponent | NzConfirmComponent>): NzModalSubject { // 在body的内部最前插入一个<nz-modal></nz-modal>方便进行ApplicationRef.bootstrap document.body.insertBefore(document.createElement(factory.selector), document.body.firstChild); // document.body.appendChild(document.createElement(factory.selector)); let customComponentFactory: ComponentFactory<NzModalComponent | NzConfirmComponent>; let compRef: ComponentRef<NzModalComponent | NzConfirmComponent>; let instance: NzModalComponent | NzConfirmComponent; let subject: NzModalSubject; if (props[ 'nzContent' ] instanceof Type) { customComponentFactory = this._cfr.resolveComponentFactory(props[ 'nzContent' ]); // 将编译出来的ngmodule中的用户component的factory作为modal内容存入 props[ 'nzContent' ] = customComponentFactory; } compRef = this._appRef.bootstrap(factory); instance = compRef.instance; subject = instance.subject; [ 'onOk', 'onCancel' ].forEach((eventType: string) => { subject.on(eventType, () => { const eventHandler = props[ eventType ]; if (eventHandler) { eventHandler(() => { instance.nzVisible = false; setTimeout(() => { compRef.destroy(); }, 200); }, instance); } }); }); Object.assign(instance, props, { nzVisible: true }); return subject; } // protected createComponentModule (componentType: any) { // @NgModule({ // declarations: [ componentType ] // }) // class CustomComponentModule {} // return CustomComponentModule; // } /** * Open modal dialog */ open(config: ConfigInterface): NzModalSubject { const options: ModalOptions = new ModalOptions(); const props = this._initConfig(config, options); return this._open(props, this._modalCompFactory); } /** * Open confirm dialog */ _openConfirm(config: ConfigInterface): NzModalSubject { const options: ConfirmOptions = new ConfirmOptions(); const props = this._initConfig(config, options); return this._open(props, this._confirmCompFactory); } /** * Open info dialog */ info(props: ConfigInterface): NzModalSubject { /* tslint:disable-next-line:no-any */ const config: any = { ...{ confirmType: 'info', iconType : 'info-circle' }, ...props }; return this._openConfirm(config); } /** * Open success dialog */ success(props: ConfigInterface): NzModalSubject { /* tslint:disable-next-line:no-any */ const config: any = { ...{ confirmType: 'success', iconType : 'check-circle' }, ...props }; return this._openConfirm(config); } /** * Open error dialog */ error(props: ConfigInterface): NzModalSubject { /* tslint:disable-next-line:no-any */ const config: any = { ...{ confirmType: 'error', iconType : 'cross-circle' }, ...props }; return this._openConfirm(config); } /** * Open warning dialog */ warning(props: ConfigInterface): NzModalSubject { /* tslint:disable-next-line:no-any */ const config: any = { ...{ confirmType: 'warning', iconType : 'exclamation-circle' }, ...props }; return this._openConfirm(config); } /** * Open confirm dialog */ confirm(props: ConfigInterface): NzModalSubject { /* tslint:disable-next-line:no-any */ const config: any = { ...{ confirmType: 'confirm', okText : this._locale.translate('Modal.okText'), cancelText : this._locale.translate('Modal.cancelText') }, ...props }; return this._openConfirm(config); } }