/* * @Author: 疯狂秀才(Lucas Huang) * @Date: 2019-08-15 15:24:24 * @LastEditors: 疯狂秀才(Lucas Huang) * @LastEditTime: 2019-11-30 14:01:34 * @QQ: 1055818239 * @Version: v0.0.1 */ import { Subscription, Observable, of, Subject } from 'rxjs'; import { Component, Input, Output, EventEmitter, TemplateRef, ViewChild, Injector, forwardRef, OnInit, ElementRef, ChangeDetectorRef, AfterViewChecked, HostBinding, NgZone, OnDestroy } from '@angular/core'; import { NG_VALUE_ACCESSOR, ControlValueAccessor, NgControl } from '@angular/forms'; import { DialogComponent } from '@farris/ui-dialog'; import { IResizeEvent } from '@farris/ui-draggable'; import { PickingResult, PickedResult } from './lookup-grid-options'; export const LOOKUPINPUT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => LookupComponent), multi: true }; @Component({ selector: 'farris-lookup', template: `
`, styles: [ ` .input-group { flex-wrap: nowrap; } :host-context(.ng-invalid) .form-control { border-color: #ff0303; } ` ], providers: [LOOKUPINPUT_VALUE_ACCESSOR] }) export class LookupComponent implements OnInit, ControlValueAccessor, AfterViewChecked, OnDestroy { @HostBinding('class') hostCls = 'f-cmp-inputgroup'; /** 窗口宽度 */ @Input() dialogWidth: number; /** 窗口高度 */ @Input() dialogHeight: number; /** 窗口标题。默认值:此处显示帮助标题 */ @Input() title = ''; /** 按钮对齐方式 */ @Input() buttonAlign = 'right'; /** 按钮模板 */ @Input() buttonsRef: TemplateRef; /** 是否显示按钮 */ @Input() showButtons = true; /** 显示关闭按钮 */ @Input() showCloseButton = true; /** 显示最大化按钮 */ @Input() showMaxButton = true; /** 允许拖拽尺寸 */ @Input() resizable = true; /** 允许拖动窗口 */ @Input() draggable = true; /** 禁用 */ @Input() disabled = false; /** 允许编辑文本框 */ @Input() editable = true; /** 只读 */ @Input() readonly = false; /** 字段映射, { 帮助数据字段:表单字段 } */ @Input() mapFields: { [sourceField: string]: string }; /** 值字段 */ @Input() valueField: string; /** 文本字段 */ @Input() textField: string; @Input() displayText = ''; /** 运行时上下文自定义对象 */ @Input() context: any; /** 窗口打开前事件 */ @Input() beforeOpen: () => Observable; /** 窗口关闭前事件 */ @Input() beforeClose: () => Observable; /** 帮助前事件 */ @Input() dictPicking: (emptyObj?: {}) => Observable; dictPickingSubscription: Subscription; /** 帮助后事件 */ @Input() dictPicked: (rowData: any) => Observable; dictPickedSubscription: Subscription; /** 窗口打开后 */ @Output() dialogOpened = new EventEmitter(); /** 窗口关闭后 */ @Output() dialogClosed = new EventEmitter(); /** 窗口最大化 */ @Output() dialogMaxed = new EventEmitter(); /** 拖拽改变窗口尺寸进行时 */ @Output() resizing = new EventEmitter(); /** 拖拽改变窗口尺寸结束 */ @Output() resized = new EventEmitter(); /** 帮助窗口默认尺寸 */ private defaultDialogSize = { width: 550, height: 570 }; dialogCreated = new Subject(); dialogCreatedSubscription: Subscription; dialog: DialogComponent; @ViewChild('dialog') set content(content: DialogComponent) { this.dialog = content; if (content) { this.dialogCreated.next(this.dialog); } } private _isShow = false; get isShow() { return this._isShow; } set isShow(val) { this._isShow = val; if (!this.changeDetector['destroyed']) { this.changeDetector.detectChanges(); } } ngControl: any; displayValue = ''; originalText = ''; get invalid() { return this.ngControl.valid; } private ngZone: NgZone; onModelChange = (obj: any) => { }; onModelTouched = (val: any) => { }; constructor( public injector: Injector, public el: ElementRef, public changeDetector?: ChangeDetectorRef ) { this.ngZone = this.injector.get(NgZone); // if (!this.personalConfigService) { // const idServ = this.injector.get(IdService); // this.personalConfigService = new PersonalConfigService(idServ); // } } ngOnInit(): void { this.initEvents(); this.ngControl = this.injector.get(NgControl, null); } ngOnDestroy() { this.lookupUnsubscribe(); } ngAfterViewChecked() { if (this.dialog) { this.dialog.closed.subscribe(() => { this.isShow = false; this.dialog = null; }); } } initEvents() { if (!this.dictPicking) { this.dictPicking = () => of({ showDialog: true }); } if (!this.dictPicked) { this.dictPicked = () => of({ closeDialog: true }); } if (!this.beforeOpen) { this.beforeOpen = () => of(true); } if (!this.beforeClose) { this.beforeClose = () => of(true); } if (!this.dialogHeight) { this.dialogHeight = this.defaultDialogSize.height; } if (!this.dialogWidth) { this.dialogWidth = this.defaultDialogSize.width; } } showDialog(): any { if (this.disabled || this.readonly) { return false; } this.dictPicking().subscribe((val: PickingResult) => { if (val.showDialog === false) { return; } this.isShow = true; // this.changeDetector.detectChanges(); this.ngZone.runOutsideAngular(() => { setTimeout(() => this.dialog.show()); }); }); return false; } closeDialog() { this.isShow = false; if (this.dialog) { this.dialog.close(); } } private lookupUnsubscribe() { if (this.dictPickedSubscription) { this.dictPickedSubscription.unsubscribe(); } if (this.dictPickingSubscription) { this.dictPickingSubscription.unsubscribe(); } if (this.dialogCreatedSubscription) { this.dialogCreatedSubscription.unsubscribe(); } } onResizing(pos: IResizeEvent) { this.resizing.emit(pos.size); } onResized(pos: IResizeEvent) { this.resized.emit(pos.size); } onMaxDialog(pos: IResizeEvent) { this.dialogMaxed.emit(pos.size); } writeValue(obj: any): void { if (obj) { this.displayText = obj; this.displayValue = obj; this.originalText = this.displayText; } else { this.displayText = ''; this.displayValue = ''; this.originalText = ''; } } registerOnChange(fn: any): void { this.onModelChange = fn; } registerOnTouched(fn: any): void { this.onModelTouched = fn; } setDisabledState?(isDisabled: boolean): void { this.disabled = isDisabled; } }