import { CtlInput } from '../input/CtlInput' import { parseYvanPropChangeVJson } from '../../CtlUtils' import { CtlMultiComboDefault } from '../../CtlDefaultValue' import { getFirstPinyin } from '../../Utils' import { DataSource } from '../../YvanDataSource' import { YvEvent, YvEventDispatch } from '../../YvanEvent' import { YvDataSource } from '../../YvanDataSourceImp' export class CtlMultiCombo extends CtlInput { static create(module: any, vjson: any): CtlMultiCombo { const that = new CtlMultiCombo(vjson) that._module = module _.defaultsDeep(vjson, CtlMultiComboDefault) // 基础属性先执行 that._create(vjson, that) const yvanProp = parseYvanPropChangeVJson(vjson, ['options', 'dataSource', 'onDataComplete', 'getRemoteData']) // 将 yvanProp 合并至当前 Ctl 对象 _.assign(that, yvanProp) _.merge(vjson, that._webixConfig) return that } /** * 数据绑定完成后触发 */ onDataComplete?: YvEvent /** * 获取远程数据触发 */ getRemoteData?: YvEvent /** * 修改下拉选项 */ set options(nv: any[]) { const options: any = { filter(item: any, filterWord: string) { if (_.size(filterWord) <= 0) { return true } const nodePy = getFirstPinyin(item.text).toLowerCase() return ( nodePy.indexOf(filterWord.toLowerCase()) >= 0 || item.text.indexOf(filterWord) >= 0 ) }, body: { template: '#text#', type: { height: 36 }, data: nv } } if (!this._webix) { _.merge(this._webixConfig, { view: 'multicombo', options }) return } this._webix.define('options', options) this._webix.refresh() } /** * 修改下拉选项 */ set dataReal(nv: any[]) { this.options = nv } /** * 值分隔符 */ get separator(): string { if (!this._webix) { return this._webixConfig.separator } return this._webix.config['separator'] } /** * 值分隔符 */ set separator(nv: string) { if (!this._webix) { this._webixConfig.separator = nv } else { this._webix.define('separator', nv) } } /** * 设置值 (如果不符合规定的格式 会清空) */ set value(nv: any) { if (!this._webix) { this._webixConfig.value = nv } else { this._webix.setValue(nv) } } /** * 获取值(可能取到空值) */ get value(): any { return this._webix.getValue() } /** * 获取显示的值 */ getText(): string { return this._webix.getText() } /** * 获取数据源设置 */ get dataSource(): DataSource { return this._dataSource } /** * 设置数据源 */ set dataSource(nv: DataSource) { this._dataSource = nv if (this._module.loadFinished) { // onLoad 之后会触发 view.onInited -> attachHandle -> refreshState -> _rebindDataSource // onLoad 之前都不需要主动触发 _rebindDataSource this._rebindDataSource() } } /* =============================================== 以下部分为私有函数 =============================================== */ //数据源设置 private _dataSource: DataSource //数据源管理器 private dataSourceBind?: YvDataSource //重新绑定数据源 private _rebindDataSource() { if (!this._module) { return; } const innerMethod = () => { if (this.dataSourceBind) { this.dataSourceBind.destory() this.dataSourceBind = undefined } if (this._webix && this._module) { this.dataSourceBind = new YvDataSource(this, this.dataSource, this._dataSourceProcess.bind(this)) this.dataSourceBind.init() } } if (!this._module.loadFinished) { // onload 函数还没有执行(模块还没加载完), 延迟调用 rebind _.defer(innerMethod) } else { // 否则实时调用 rebind innerMethod() } } private _dataSourceProcess(data: any[]) { if ( !this.dataSource || _.isArray(this.dataSource) || _.isFunction(this.dataSource) ) { YvEventDispatch(this.getRemoteData, this, data) return data } if (this.dataSource.type !== 'SQL') { YvEventDispatch(this.getRemoteData, this, data) return data } const displayField = this.dataSource.displayField || 'text' const valueField = this.dataSource.valueField || 'id' const remoteData = _.map(data, item => { return { id: item[valueField], text: item[displayField] } }) YvEventDispatch(this.getRemoteData, this, remoteData) return remoteData } //刷新状态时,自动重绑数据源 protected refreshState() { super.refreshState() this._rebindDataSource() } }