import { Component, OnInit, Input, forwardRef, NgModule, TemplateRef, Output, EventEmitter, ViewChild } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from "@angular/forms"; import { CommonModule } from "@angular/common"; import { NgZorroAntdModule } from 'ng-zorro-antd'; import { Subject } from 'rxjs/Rx'; import { ApiService } from '../services/api.service'; declare let _; export interface GoodOpt { name: string; goodId?: string; disabled?: boolean; } export interface DomOpt { _value: string; _label: string; } export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StandardGoodComponent), multi: true }; @Component({ selector: `standard-good`, template: `
`, styles: [` .close-icon { opacity: 0; position: absolute; right: 20px; top: 50%; margin-top: -10px; } .close-icon:hover { opacity: 1; } .good-nz-select:hover +.close-icon { opacity: 1; } .good-select { position: relative; } .echo-loading { position: absolute; left: 0; top: 0; width: 100%; min-height: 28px; } .loading-pos { position: absolute; left: 10px; top: 6px; } `], providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR] }) export class StandardGoodComponent implements ControlValueAccessor, OnInit { @ViewChild("domOpt") domOpt: DomOpt; private onTouchedCallback: () => () => {}; private onChangeCallback: (_: any) => () => {}; options: Array = []; // 单选的时候传字符串,多选传数组 _value: string; _width = "100%"; _content: TemplateRef; _allowClear = true; _nzMode = "combobox"; // 下拉过滤含关键字选项,false为不过滤 _filter = false; _placeholder = "" currentText = ""; firstNum = 1; canQuery = true; loading = false; keyWordStream = new Subject() keyWord$: any; @Input() goodId = ""; @Input() placeholder = "请选择品名"; @Input() rowsNum = 10; @Input() valueType = ""; @Input() nzDisabled = false; set value(v: any) { if (!v) { this.canQuery = true; this.firstNum = 1; this.queryData('', []); this.onChangeCallback({}); return; } // 防止重复赋值 if (_.isEqual(this._value, v)) return; this._value = v; // 双向绑定获取对象 if (this.valueType === "object") { this.onChangeCallback(v); } else if(this.valueType === "objectString") { this.onChangeCallback(`{standProductName: ${v.name}, standProductId: ${v.code}}`) } else { const innerValue = this._allowClear ? (v.goodId || "") : (>v.map(val => val.goodId) || []); this.onChangeCallback(innerValue); } } get value(): any { return this._value; }; @Input() set width(v: any) { const width = parseInt(v); this._width = (Array.from(v)).includes("%") ? `${v}%` : isNaN(width) ? this._width : `${width}px`; } @Input() set goodMode(v) { this._nzMode = v; this._allowClear = v === "combobox" ? true : false; }; @Input() set customTemplate(tpl: TemplateRef) { if (tpl instanceof TemplateRef) { this._content = tpl; } } @Output() openChange = new EventEmitter(); @Output() onChange = new EventEmitter(); constructor(private api: ApiService) { } ngOnInit() { // 限流 this.keyWord$ = this.keyWordStream .debounceTime(250) .subscribe(word => { this.queryData(word, []); }); this._placeholder = this.placeholder; } ngOnChanges(changes: any) { if (changes.goodId && this.goodId) { this.firstNum = 1; this.loading = true; this.queryData(this.goodId, [], true); } if (changes.customerId) { this.firstNum = 1; this.loading = true; this.canQuery = true; this.queryData(this.goodId, []); } } ngOnDestroy() { this.keyWord$.unsubscribe() } // 写入值 writeValue(value: any) { if (value !== this._value) { this._value = value; if (value) { this.currentText = value.name; this.firstNum = 1; this.loading = true; this._placeholder = ''; if (value.name) { this.queryData(value.name, [], true); } else { this.queryData(value, [], true); } } } } // 注册变化处理事件 registerOnChange(fn: any) { this.onChangeCallback = fn; } // 注册触摸事件 registerOnTouched(fn: any) { this.onTouchedCallback = fn; } yztSearchChange(event) { this.canQuery = true; this.currentText = event; this.firstNum = 1; this.keyWordStream.next(event); } yztScrollToBottom() { this.queryData(this.currentText, this.options); } /** * 仅作清空多选选项 */ clearSelect($event?: MouseEvent): void { if ($event) { $event.preventDefault(); $event.stopPropagation(); } this.options = []; this.value = ''; } /** * 查询数据 * @param $event */ queryData(searchText?: string, options?: Array, firstIn: boolean = false) { if (!this.canQuery) return; const goodName = searchText; let params; if(this.goodId) { params = [{ "page": this.firstNum, "size": this.rowsNum }, { code: this.goodId }]; } else { params = [{ "page": this.firstNum, "size": this.rowsNum }, { name: goodName }]; } this.api.getStandarGood(params as any).subscribe(json => { let content = json && json['content'] || {}; let result = content['content'] || [] this.options = options.concat(result); this.firstNum += 1; if (firstIn || this.goodId) { this.value = this.options[0]; } this.loading = false; this._placeholder = this.placeholder; if (!result.length) { this.options.push({ goodId: "empty", name: "没有更多选项!", disabled: true }); this.canQuery = false; } }) } } @NgModule({ imports: [ CommonModule, FormsModule, NgZorroAntdModule, ], declarations: [ StandardGoodComponent ], exports: [StandardGoodComponent] }) export class StandardGoodModule { }