import { Injectable, ComponentFactoryResolver, Injector, ComponentRef } from '@angular/core'; import { BsModalService, BsModalRef } from '@farris/ui-modal'; import { SelectorComponent } from '../selector.component'; import { DisplayType, isValidOptions, PRIMARY_KEY, ShowOptions } from '../types'; @Injectable() export class SelectorService { private options: ShowOptions; public modalRef: BsModalRef = null; private componentRef: ComponentRef = null; constructor( public injector: Injector, private modalService: BsModalService, private componentFactoryResolver: ComponentFactoryResolver ) { } /** * 显示选择器 * @param options options */ public show(options: ShowOptions) { if (!isValidOptions(options)) { throw new Error('not a valid options.'); } this.options = options; // options is valid from now const componentFactory = this.componentFactoryResolver.resolveComponentFactory(SelectorComponent); this.componentRef = componentFactory.create(this.injector); // configure properties this.configureProperties(options); this.configureOptionalProperties(options); // configure dialog const modalOptions = this.buildModalOptions(options); // registe event this.registeEvent(); // open modal this.modalRef = this.modalService.show(this.componentRef, modalOptions); } /** * 选择器组件引用 */ public get host(): SelectorComponent { return this.componentRef.instance; } /** * 弹框引用 */ public get dialog(): BsModalRef { return this.modalRef; } //#region event handler private onConfirm(event: any) { if (this.options.onConfirm && typeof this.options.onConfirm === 'function') { // 组织最终数据 const items = this.host.items; const item = this.host.currentItem; const id = this.host.currentItem && this.host.currentItem[this.host.primaryKey]; const ids = this.host.checkIds; const options = { id, ids, item, items }; this.options.onConfirm(options); this.dialog.close(); } } private onCancel() { if (this.options && typeof this.options.onCancel === 'function') { this.options.onCancel(); } } //#endregion private registeEvent() { if (!this.host) { return; } this.host.dblClick.subscribe((event: any) => { if (this.host.multi) { return; } this.onConfirm(event); }); } private configureProperties(options: ShowOptions) { if (!this.host) { return; } const { displayType = DisplayType.treetable, columns = [], items = [], editable = false, idField = 'id' } = options || {}; this.host.displayType = displayType; // 可编辑时新增操作列 if (editable) { this.appendOperateColumn(options); } if (displayType === DisplayType.datagrid) { // 添加主键字段 } // 如果使用grid组件,则将主键设置为默认的主键,不使用用户主键 if (displayType === DisplayType.datagrid) { this.host.primaryKey = PRIMARY_KEY; columns.push({ title: '*', field: PRIMARY_KEY, visible: false }); } else { this.host.primaryKey = idField; } this.host.columns = columns; // 处理主键数据 const data = items.map((item: any, index: number) => { if (displayType === DisplayType.datagrid) { item[PRIMARY_KEY] = index + 1; } return item; }); this.host.items = data; } /** * 添加操作列 * @param options options */ private appendOperateColumn(options: ShowOptions) { const { displayType = DisplayType.treetable, columns = [] } = options || {}; if (displayType === DisplayType.treetable) { throw new Error('树组件不支持编辑。'); } columns.push({ title: '操作', width: 60, template: this.host.operateCell, halign: 'center', align: 'center', fixed: 'right' }); } /** * 配置组件可选属性 * @param options options * @returns */ private configureOptionalProperties(options: ShowOptions) { if (!this.host) { return; } if (typeof options.width === 'number') { this.host.width = options.width; } if (typeof options.height === 'number') { this.host.height = options.height; } if (typeof options.title === 'string' && options.title.length > 0) { this.host.title = options.title; } // if (typeof options.idField === 'string' && options.idField.length > 0) { // this.host.idField = options.idField; // } if (typeof options.disabled === 'boolean') { this.host.disabled = options.disabled; } if (typeof options.multi === 'boolean') { this.host.multi = options.multi; } if (typeof options.showFilterBar === 'boolean') { this.host.showFilterBar = options.showFilterBar; } if (typeof options.fit === 'boolean') { this.host.fit = options.fit; } if (typeof options.showHeader === 'boolean') { this.host.showHeader = options.showHeader; } if (typeof options.showBorder === 'boolean') { this.host.showBorder = options.showBorder; } if (typeof options.fitColumns === 'boolean') { this.host.fitColumns = options.fitColumns; } if (typeof options.showCheckbox === 'boolean') { this.host.showCheckbox = options.showCheckbox; } if (typeof options.showCheckAll === 'boolean') { this.host.showCheckAll = options.showCheckAll; } if (typeof options.striped === 'boolean') { this.host.striped = options.striped; } if (typeof options.virtualized === 'boolean') { this.host.virtualized = options.virtualized; } if (typeof options.sortName === 'string' && options.sortName.length > 0) { this.host.sortName = options.sortName; } if (['asc', 'desc'].includes(typeof options.sortOrder)) { this.host.sortOrder = options.sortOrder; } // editable not support if (typeof options.editable === 'boolean') { this.host.editable = options.editable; } if (typeof options.keepSelect === 'boolean') { this.host.keepSelect = options.keepSelect; } } private buildModalOptions(options: ShowOptions) { const { width = 450, height = 400, title = '选择器', showButtons = true, showCloseButton = true, showMaxButton = true, resizable = true, draggable = true } = options; const defaultButtons = [ { text: '取消', cls: 'btn btn-secondary', handle: () => { this.onCancel(); this.dialog.close(); } }, { text: '确定', cls: 'btn btn-primary', handle: () => { this.onConfirm(null); } } ]; const buttons = options.buttons || defaultButtons; const modalOptions: any = { title, width, height, enableScroll: false, showCloseButton, showMaxButton, draggable, resizable, buttons: buttons, showButtons: showButtons, areaResponse: true, initialState: options }; return modalOptions; } }