Przeglądaj źródła

combogrid 初步完成

luoyifan 3 lat temu
rodzic
commit
b42216f000
3 zmienionych plików z 138 dodań i 91 usunięć
  1. 15 0
      src/Defaults.ts
  2. 24 25
      src/controls/grid.js
  3. 99 66
      src/controls/input/combogrid.js

+ 15 - 0
src/Defaults.ts

@@ -26,6 +26,21 @@ export const combo = {
     enableKeyEvents: true,
 }
 
+export const comboGrid = {
+    selectOnTab: true,
+    pickerHeight: 500,
+    pickerWidth: 850,
+}
+
+export const comboGridPicker = {
+    xtype: 'yvgrid',
+    layout: 'fit',
+    selModel: {
+        selType: 'rowmodel',
+        mode: 'SINGLE'
+    },
+}
+
 export const numberfield = {
     labelAlign: 'right',
     labelWidth: 70,

+ 24 - 25
src/controls/grid.js

@@ -3,7 +3,7 @@ import {grid} from '../Defaults'
 import {baseConfig} from "./base";
 import {lookupFn, lookupScope} from "../lib/lib";
 import {serverInvokeUrlTransform} from "../lib/config";
-import {calcObject} from "../lib/systemLib";
+import {calcObject, calcObjectFlat} from "../lib/systemLib";
 import {
     disabled,
     fieldLabel,
@@ -162,31 +162,30 @@ export default function () {
             if (_.isPlainObject(dataSource) && dataSource.method === 'invoke' && !window["IS_DESIGN_MODE"]) {
                 const scope = lookupScope(me)
 
-                calcObject(scope.viewModel, dataSource.params).then(params => {
-
-                    me.setStore(new Ext.data.Store({
-                        remoteSort: config.remoteSort,
-                        remoteFilter: config.remoteFilter,
-                        proxy: {
-                            type: 'jsonAjax',
-                            $owner: me,
-                            url: serverInvokeUrlTransform(dataSource.url),
-                            extraParams: _.defaultsDeep({}, reloadParams, params),
-                            reader: {
-                                type: 'json',
-                                rootProperty: 'data',
-                                totalProperty: 'pagination.total',
-                                successProperty: 'success',
-                                messageProperty: 'msg'
-                            }
-                        },
-                        listeners: {
-                            load: function (store, records, successful, operation) {
-                                me.fireEvent('dataLoadComplete', me, successful, records);
-                            }
+                const params = calcObjectFlat(scope.viewModel.data, dataSource.params)
+                me.setStore(new Ext.data.Store({
+                    remoteSort: config.remoteSort,
+                    remoteFilter: config.remoteFilter,
+                    autoLoad: true,
+                    proxy: {
+                        type: 'jsonAjax',
+                        $owner: me,
+                        url: serverInvokeUrlTransform(dataSource.url),
+                        extraParams: _.defaultsDeep({}, reloadParams, params),
+                        reader: {
+                            type: 'json',
+                            rootProperty: 'data',
+                            totalProperty: 'pagination.total',
+                            successProperty: 'success',
+                            messageProperty: 'msg'
                         }
-                    }))
-                })
+                    },
+                    listeners: {
+                        load: function (store, records, successful, operation) {
+                            me.fireEvent('dataLoadComplete', me, successful, records);
+                        }
+                    }
+                }))
             }
         },
 

+ 99 - 66
src/controls/input/combogrid.js

@@ -1,4 +1,6 @@
 import _ from 'lodash'
+import {comboGrid, comboGridPicker} from '../../Defaults'
+import {calcObjectFlat, clearViewModelByLookup, lookupScope, stopEvent, tryWriteByExpress, tryWriteObject} from "../..";
 
 export default function () {
 
@@ -19,44 +21,41 @@ export default function () {
         },
 
         config: {
-            selectOnTab: true,
-            pickerHeight: 500,
-            pickerWidth: 750,
+            ...comboGrid
         },
 
         editable: true,
+        _superBlur: false,
 
         initComponent() {
             const that = this
-            const toggle = function (e) {
-                // @ts-ignore
-                const {readOnly, disabled} = that.config
-                if (readOnly || disabled) {
-                    return
-                }
-
-                // 点击后下拉
-                if (that.isExpanded) {
-                    // that.collapse()
-
-                } else {
-                    that.expand();
-                }
-            }
 
             this.on({
                 blur(sender, e) {
-                    this.revertOnblur()
+                    if (this._superBlur) {
+                        // 挂起时不恢复内容
+                        return
+                    }
+
+                    // 离开焦点时,恢复原来的值
+                    sender.setRawValue(sender.value)
                 },
                 afterrender(sender) {
-                    const $dom = $(sender.el.dom)
-                    $dom.on('keydown', (e) => {
+                    const $dom = $(sender.inputEl.dom)
+                    $dom.on('keyup', (e) => {
                         if (e.key === 'Enter') {
-                            toggle();
-                            e.stopPropagation();
-                            e.preventDefault();
+                            that.onTriggerClick(that, that.getPickerTrigger(), e);
                             return
                         }
+                        // 取消 keyup 事件,让 ext 不要吧当前输入的值记录到 value 中
+                        stopEvent(e)
+                    })
+                    $dom.on('input', e => {
+                        that.filterChange(that, e.target.value)
+                        stopEvent(e)
+                    })
+                    $dom.on('change', e => {
+                        stopEvent(e)
                     })
                 },
                 // 这里不能用 specialkey, 在表格编辑时可能出 bug
@@ -98,13 +97,9 @@ export default function () {
                 maxHeight: me.pickerHeight,
                 items: [
                     {
-                        xtype: 'yvgrid',
-                        layout: 'fit',
-                        selModel: {
-                            selType: 'rowmodel',
-                            mode: 'SINGLE'
-                        },
+                        ...comboGridPicker,
                         ...me.grid,
+                        autoLoad: false,
                         listeners: {
                             afterrender(grid) {
                                 me.grid = grid
@@ -118,7 +113,7 @@ export default function () {
                                             me.setFocus()
                                         })
                                     },
-                                    keydown(sender, e) {
+                                    keyup(sender, e) {
                                         me.processKey(e)
                                     }
                                 })
@@ -141,6 +136,8 @@ export default function () {
         processKey(e) {
             if (e.key === 'Enter') {
                 this.selectItem(this.grid.selection)
+                stopEvent(e)
+
             } else if (e.key === 'Escape') {
                 this.collapse()
             }
@@ -162,63 +159,99 @@ export default function () {
             }
         },
 
+        filterChange: _.debounce((sender, value) => {
+            sender.onExpand()
+
+        }, 1000),
+
         selectItem(record) {
-            var me = this;
-            me.setValue(record.getId());
-            me.fireEvent('select', me, record);
+            const me = this;
+            const {lookup} = this
+            const scope = lookupScope(this)
+
+            me.fireEvent('select', me, record)
+
+            if (record.isModel) {
+                record = record.data
+            }
+            tryWriteObject(lookup, record, (path, value) => {
+                if (path === 'queryValue') {
+                    me.setValue(value)
+                } else {
+                    scope.viewModel.set(path, value)
+                }
+            })
+
             me.collapse();
         },
 
         onExpand() {
-            const picker = this.picker;
-            this.setFocus()
+            // 展开时,根据 lookup 带入查询参数
+            const {param} = this
+            const scope = lookupScope(this)
+            const reloadParam = calcObjectFlat({
+                ...scope.viewModel.data,
+                queryValue: this.getRawValue()
+            }, param)
+
+            this.grid.reload(reloadParam)
         },
 
-        onCollapse() {
-
+        onTriggerClick() {
+            const {isExpanded, readOnly, disabled} = this
+            if (isExpanded || readOnly || disabled) {
+                // 已弹出、只读、禁用状态下,不允许弹出
+                return
+            }
+            this._superBlur = true
+            this.superclass.onTriggerClick.apply(this, arguments)
+            this._superBlur = false
         },
 
-        revertOnblur() {
-            this.setRawValue(this.lastValue)
+        onCollapse() {
+            // 每次收回时,删除下拉组件
+            // delete this.picker
         },
 
+        /**
+         * 本方法只会从 API 或外部调用,键盘输入的内容不会记录在内
+         */
         setValue(value) {
             const me = this;
-            console.log('setValue', value)
-            me.value = value;
-
-            if (!me.store || me.store.loading) {
-                // Called while the Store is loading. Ensure it is processed by the onLoad method.
-                return me.mixins.field.setValue.call(me, value);
-                // return me;
-            }
-
-            let record = value ? me.store.getNodeById(value) : me.store.getRoot();
-            if (value === undefined) {
-                record = me.store.getRoot();
-                console.log('setValue', record.getId())
-                me.value = record.getId();
-                return me.mixins.field.setValue.call(me, value);
 
-            } else {
-                record = me.store.getNodeById(value);
-            }
-
-            // set the raw value to the record's display field if a record was found
-            me.setRawValue(record ? record.get(me.displayField) : '');
+            // 设值用户看到的表面内容
+            this.setRawValue(value);
 
+            // 设值 setValue 调用链,正常触发 change 事件等
             return me.mixins.field.setValue.call(me, value);
         },
 
-        getSubmitValue() {
-            return this.value;
-        },
+        onChange: function (newVal, oldVal) {
+            const me = this
+            const value = newVal
 
-        getValue() {
-            return this.value;
+            if (value) {
+                me.getTrigger('clear').show();
+                me.updateLayout();
+            } else {
+                me.getTrigger('clear').hide();
+                me.updateLayout();
+            }
         },
 
+        /**
+         * 清空所有值
+         */
+        onClearClick(sender, e) {
+            const me = this
+            const {config} = me
+            const {lookup} = config
+
+            me.fireEvent('clear', sender, e)
 
+            me.setValue('')
+            clearViewModelByLookup(sender, lookup)
+        }
     });
 
 }