import { ComboPanelComponent } from './../combo-panel.component'; import { Component, OnInit, ElementRef, NgZone, Renderer2, ChangeDetectorRef, forwardRef, Inject, Input, Injector, EventEmitter, Output, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { cloneDeep } from 'lodash-es'; import { of, Observable } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { CommonUtils } from '@farris/ui-common'; import { DataColumn } from '@farris/ui-common/column'; import { EntityFilter } from '@farris/ui-common/types'; import { MessagerService } from '@farris/ui-messager'; import { LoadingComponent, LoadingService } from '@farris/ui-loading'; import { TreeInfo, ILookupHttpService, ServerSideToken, RemoteParams, SearchParam } from '@farris/ui-lookup'; import { ComboComponent } from '../combo.component'; import { ComboService } from '../combo.service'; import { DEFAULT_COMBOSTATE, COMBO_FACADE_SERVICE } from '../core/combo-types'; import { DefaultComboLookupState } from './combo-lookup.state'; import { ComboLookupService } from './combo-lookup.service'; export const INPUT_COMBOLOOKUP_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ComboLookupComponent), multi: true }; @Component({ selector: 'farris-combolookup', templateUrl: './combo-lookup.component.html', providers: [ INPUT_COMBOLOOKUP_VALUE_ACCESSOR, { provide: DEFAULT_COMBOSTATE, useValue: DefaultComboLookupState }, { provide: COMBO_FACADE_SERVICE, useClass: ComboLookupService, deps: [DEFAULT_COMBOSTATE] } ] }) export class ComboLookupComponent extends ComboComponent implements OnInit { @Input() displayType: 'List' | 'TreeList' = 'List'; @Input() idField: string; @Input() columns: DataColumn[] = []; @Input() textField: string; @Input() valueField: string; @Input() pagination: boolean; @Input() condition: EntityFilter; @Input() pageList = []; @Input() pageSize = 20; @Input() pageIndex = 1; @Input() treeInfo: TreeInfo; @Input() data: any; @Input() uri: string; @Input() multiSelect = false; @Input() customData: any; @Output() selected = new EventEmitter(); private http: ILookupHttpService; private loading: LoadingComponent; constructor( public el: ElementRef, public zone: NgZone, public render: Renderer2, public cd: ChangeDetectorRef, @Inject(COMBO_FACADE_SERVICE) public cmbLookup: ComboLookupService, public cmbState: ComboService, private utils: CommonUtils, private injector: Injector, private messagerService: MessagerService, private loadingService: LoadingService ) { super(el, zone, render, cd, cmbLookup, cmbState); this.panelAlign = 'left'; this.panelWidth = 500; this.panelHeight = 400; this.http = this.injector.get(ServerSideToken); } ngOnInit() { super.ngOnInit(); this.initCtrlState(); this.onPanelOpened(); this.cmbLookup.selections$.pipe( debounceTime(0) ).subscribe(items => { if (items && items.length) { this.displayText = items.map(item => this.utils.getValue(this.textField, item)).join(','); } else { this.displayText = ''; } this.onModelChange(this.displayText); // this.updateValues(items); // this.updateChanges(); }); } private initCtrlState() { const { idField, textField, valueField, multiSelect, pagination, pageList, pageIndex, pageSize, treeInfo, columns } = { ...this }; const pageInfo = { pagination, pageList, pageIndex, pageSize, total: 0 }; this.cmbLookup.initControlState({ idField, valueField, textField, multiSelect, pageInfo, treeInfo, columns }); } private showLoading() { this.loading = this.loadingService.show(); } private closeLoading() { if (this.loading) { this.loading.close(); this.loading = null; } } private onPanelOpened() { this.cmbLookup.isOpenChange.subscribe((isopen: boolean) => { if (isopen) { this.initData(); } }); this.cmbState.comboPanelCreated.subscribe((cmbPanel: ComboPanelComponent) => { if (document && document.body && cmbPanel) { document.body.appendChild(cmbPanel.el.nativeElement); } }); } private initData() { switch (this.displayType) { case 'TreeList': { break; } default: // List { this.getData().subscribe(data => this.loadDataTable(data)); } } } private getData(event?: { pageInfo: any, search: any }, dataType: any = 'all'): Observable { if (this.uri) { const params: RemoteParams = {}; if (this.condition) { params.condition = cloneDeep(this.condition); } const searchParam: SearchParam = { category: dataType }; if (event) { if (event.pageInfo) { params.pageIndex = event.pageInfo.pageIndex; params.pageSize = event.pageInfo.pageSize; } if (event.search) { searchParam.searchField = event.search.field; searchParam.searchValue = event.search.value; } } params['searchValue'] = JSON.stringify(searchParam); params['customData'] = this.customData; this.showLoading(); return this.http.getData(this.uri, params); } else { return of(false); } } private loadDataTable(resData: any) { this.closeLoading(); if (resData) { if (resData.columns && resData.columns.length) { this.columns = resData.columns; } const data = resData.items; const total = resData.total; if (resData.pageInfo) { if (resData.pageInfo.pageList) { this.pageList = resData.pageInfo.pageList; } this.pagination = resData.pageInfo.enablePager; this.pageIndex = resData.pageInfo.pageIndex; this.pageSize = resData.pageInfo.pageSize; } else { this.pagination = false; } const { pageList, pageIndex, pageSize, pagination } = { ...this }; this.cmbLookup.initControlState({ columns: this.columns, pageInfo: { pageList, pageIndex, pageSize, pagination, total }, data }); } } private loadTreeTable(data: any) { } //#region 下拉列表帮助 pagerChanged(e: any) { this.getData(e, 'list').subscribe((data: any) => { this.closeLoading(); this.loadDataTable(data); }, (err) => { this.closeLoading(); }); } onRowSelected($event: any) { const data = $event.data; this.cmbLookup.selectItem(data); if (!this.multiSelect) { this.cmbFacade.hidePanel(); } this.selected.next(data); } onRowUnSelected($event: any) { const data = $event.data; this.cmbLookup.unSelectItem(data); } //#endregion }