import { Injectable, ComponentFactoryResolver, Injector, EventEmitter, ComponentRef } from '@angular/core'; import { BatchEditDialogComponent } from './batch-edit-dialog.component'; import { BsModalService, BsModalRef } from '@farris/ui-modal'; import { LocaleService } from '@farris/ui-locale'; import { isObservable, Observable, of, Subject } from 'rxjs'; import { ResultConfirmComponent } from './result-confirm/result-confirm.component'; // tslint:disable: max-line-length @Injectable() export class BatchEditDialogService { public dialogRef: BsModalRef = null; private componentRef: ComponentRef = null; // 用户对输入进行确认,此时可以更新bindingData数据 public onUserConfirmed: EventEmitter = new EventEmitter(); constructor( public injector: Injector, private modalService: BsModalService, private componentFactoryResolver: ComponentFactoryResolver, private localeService: LocaleService, ) { } /** * @description 控件参数格式 * # 控件参数格式 * ## textbox * ```json * {"title":"姓名","field":"name","editor":{"controlType":EditorTypes.TEXTBOX}} * ``` * ## dropdown * ```json * {"title":"姓名","field":"name","editor":{"controlType":EditorTypes.COMBOLIST,"idField":"id","textField":"text","items":[],"multiSelect":false}} * ``` * ## lookup * ```json * {"title":"姓名","field":"name","editor":{"controlType":EditorTypes.LOOKUP,"uri":"","idField":"id","textField":"text","valueField":"id","displayType":"LIST","mapFields":{},"singleSelect":true,"dialogTitle":"","hiddenInputName":"","items":[],"multiSelect":false}} * ``` * ## 数值输入框 * ```json * {"title":"数值","field":"name","editor":{"controlType":EditorTypes.NUMBER,"precision":2,"step":1,"min":1,"max":10}} * ``` */ public batchEdit(columns: any, options?: { [propName: string]: any }): BsModalRef { const titleText = this.localeService.getValue('batchEditDialog.title'); const okText = this.localeService.getValue('batchEditDialog.okText'); const cancelText = this.localeService.getValue('batchEditDialog.cancelText'); const { width = 792, height = 580, title = titleText, rows = 1 } = options || {}; const componentFactory = this.componentFactoryResolver.resolveComponentFactory(BatchEditDialogComponent); this.componentRef = componentFactory.create(this.injector); this.componentRef.instance.fields = this.getFields(columns); this.componentRef.instance.eidtors = this.getEditors(columns); this.componentRef.instance.title = title; this.componentRef.instance.rows = rows; this.dialogRef = this.modalService.show(this.componentRef, { title, width, height, buttons: [ { text: cancelText, cls: 'btn btn-secondary', handle: () => { this.dialogRef.close(); } }, { text: okText, cls: 'btn btn-primary', handle: () => { this.userConfired(); } } ], showHeader: false, showButtons: false, }); this.componentRef.instance.confirmed.subscribe((e: { instance: any, event: any }) => { this.canConfirm(options).subscribe((result: boolean) => { if (result === true) { this.userConfired(options); this.dialogRef.close(); } }); }); this.componentRef.instance.canceled.subscribe((e: { instance: any, event: any }) => { this.dialogRef.close(); }); this.componentRef.instance.dialogRef = this.dialogRef; this.dialogRef.dialog.instance.draggbar.handle = this.componentRef.instance.header.nativeElement; return this.dialogRef; } /** * 用户确认修改 */ public userConfired(options?: { [propName: string]: any }) { const inputs = this.componentRef && this.componentRef.instance && this.componentRef.instance.inputs || []; // 针对checkbox做特殊处理 if (inputs && inputs.length > 0) { inputs.forEach(input => { const { controlType, dataType } = input; if (controlType === 'checkbox' && dataType === 'boolean') { input.value = input.value ? true : false; } }); } if (options && options.onConfirm && typeof options.onConfirm === 'function') { options.onConfirm(inputs); } this.onUserConfirmed.next(inputs); } /** * 从dom中获取grid列 * @param columns dom */ private getFields(columns: any): Array { const fields = []; if (!columns || columns.length < 1) { return fields; } columns.forEach((collect: Array) => { // collect为数组 if (collect && collect.length > 0) { collect.forEach((column: any) => { const { field = null, title = '', dataType = null, enableBatchEdit = false } = column || {}; if (field && enableBatchEdit) { fields.push({ id: field, label: title, dataType }); } }); } }); return fields; } /** * 从columns中获取编辑器 * @param columns dom */ private getEditors(columns: any): Array { const editors = []; if (!columns || columns.length < 1) { return editors; } columns.forEach((collect: Array) => { // collect为数组 if (collect && collect.length > 0) { collect.forEach((column: any) => { const { field = null, editor = {}, enableBatchEdit = false } = column || {}; if (editor && field && enableBatchEdit) { editor.controlType = editor.type; editors.push({ field, editor }); } }); } }); return editors; } private canConfirm(options?: { [propName: string]: any }) { const subject = new Subject(); let showNotify = options && options.showNotify; const { rows = 1 } = options || {}; const valueChanged = this.isValueChanged(); if (!valueChanged) { return of(true); } if (showNotify === undefined) { showNotify = true; } if (!showNotify) { return of(true); } let dialogRef = null; try { const componentFactory = this.componentFactoryResolver.resolveComponentFactory(ResultConfirmComponent); const componentRef = componentFactory.create(this.injector); const shouldShowNotify = componentRef.instance.showNotify || false; componentRef.instance.rows = rows; if (shouldShowNotify) { dialogRef = this.modalService.show(componentRef, { title: '', width: 500, height: 240, showHeader: false, showButtons: false, buttons: [] }); // 确认 componentRef.instance.confirmed.subscribe((e: { instance: any, event: any }) => { if (dialogRef) { dialogRef.close(); } subject.next(true); }); // 取消 componentRef.instance.canceled.subscribe((e: { instance: any, event: any }) => { if (dialogRef) { dialogRef.close(); } subject.next(false); }); } else { return of(true); } } catch (e) { return of(true); } return subject; } public isValueChanged() { const inputs = this.componentRef && this.componentRef.instance && this.componentRef.instance.inputs || []; if (!inputs || inputs.length < 1) { return false; } const unChanged = inputs.every((item) => !item.field); return !unChanged; } }