extjs7 combobox 根据输入值执行远端查询过滤选项源码分析
小编:管理员 496阅读 2022.09.06
版本
extjs 7.4.0 classic
源码ext-classic/src/form/field/Base.js
// 初始化事件时将onFieldMutation函数绑定到propertychange,textInput事件上 initEvents: function() { var me = this, inputEl = me.inputEl, onFieldMutation = me.onFieldMutation, events = me.checkChangeEvents, len = events.length, i, event; if (inputEl) { me.mon( inputEl, Ext.supports.SpecialKeyDownRepeat ? 'keydown' : 'keypress', me.fireKey, me ); for (i = 0; i < len; ++i) { event = events[i]; if (event === 'propertychange') { me.usesPropertychange = true; } if (event === 'textInput') { me.usesTextInput = true; } me.mon(inputEl, event, onFieldMutation, me); } } me.callParent(); }复制
- 在输入事件后通过延时(配置项queryDelay,默认值500)任务执行查询,避免输入过程中无效查询 ext-classic/src/form/field/ComboBox.js
onFieldMutation: function(e) { var me = this, key = e.getKey(), isDelete = key === e.BACKSPACE || key === e.DELETE, rawValue = me.inputEl.dom.value, len = rawValue.length; // Do not process two events for the same mutation. // For example an input event followed by the keyup that caused it. // We must process delete keyups. // Also, do not process TAB event which fires on arrival. if (!me.readOnly && (rawValue !== me.lastMutatedValue || isDelete) && key !== e.TAB) { me.lastMutatedValue = rawValue; me.refreshEmptyText(); if (len && (e.type !== 'keyup' || (!e.isSpecialKey() || isDelete))) { me.doQueryTask.delay(me.queryDelay); } else { // We have *erased* back to empty if key is a delete, // or it is a non-key event (cut/copy) if (!len && (!key || isDelete)) { // This portion of code may end up calling setValue will check for change. // But since it's come from field mutations, we need to respect // the checkChangeBuffer, so we suspend checks here, it will be handled // by callParent ++me.suspendCheckChange; // Essentially a silent setValue. // Clear our value, and the tplData used to construct a mathing raw value. if (!me.multiSelect) { me.value = null; me.displayTplData = undefined; } // If the value is blank we can't have a value if (me.clearValueOnEmpty) { me.valueCollection.beginUpdate(); me.pickerSelectionModel.deselectAll(); me.valueCollection.removeAll(); me.valueCollection.endUpdate(); } // Just erased back to empty. Hide the dropdown. me.collapse(); // There may have been a local filter if we were querying locally. // Clear the query filter and suppress the consequences // (we do not want a list refresh). if (me.queryFilter) { me.clearLocalFilter(); } // When queryCaching if the user deletes the value and then starts typing // the same filter again, doQuery can erroneously expand the picker without // filtering first. me.lastQuery = null; --me.suspendCheckChange; } me.callParent([e]); } } }复制
- 查询任务 ext-classic/src/form/field/ComboBox.js
// 初始化查询任务 initComponent: function() { ... me.doQueryTask = new Ext.util.DelayedTask(me.doRawQuery, me); ... } // 获取输入值执行查询 doRawQuery: function() { var me = this, rawValue = me.inputEl.dom.value; if (me.multiSelect) { rawValue = rawValue.split(me.delimiter).pop(); } me.doQuery(rawValue, false, true); } // 执行查询 doQuery: function(queryString, forceAll, rawQuery) { var me = this, store = me.getStore(), filters = store.getFilters(), // 判断是否可以,以及如何执行查询 queryPlan = me.beforeQuery({ lastQuery: me.lastQuery || '', query: queryString || '', rawQuery: rawQuery, forceAll: forceAll, combo: me, cancel: false }), refreshFilters; if (queryPlan !== false && !queryPlan.cancel) { // 如果包含查询字符串,并且但钱没有查询过滤器(正在执行查询)或与上次查询的过滤器不同,则执行查询 refreshFilters = !!queryString && (!me.queryFilter || me.queryFilter && (filters.indexOf(me.queryFilter) < 0)); // 如果与上一次查询相同则展开下拉框 if (me.queryCaching && !refreshFilters && queryPlan.query === me.lastQuery) { me.getPicker().refresh(); me.expand(); me.afterQuery(queryPlan); } // 否则执行查询并重新加载store else { me.lastQuery = queryPlan.query; if (me.queryMode === 'local') { me.doLocalQuery(queryPlan); } else { me.doRemoteQuery(queryPlan); } } return true; } else { me.startCheckChangeTask(); } return false; } // 执行远端查询,将查询字符串加入到store加载参数中 doRemoteQuery: function(queryPlan) { var me = this, loadCallback = function() { if (!me.destroyed) { me.afterQuery(queryPlan); } }; me.expand(); if (me.pageSize) { me.loadPage(1, { rawQuery: queryPlan.rawQuery, callback: loadCallback }); } else { me.store.load({ params: me.getParams(queryPlan.query), rawQuery: queryPlan.rawQuery, callback: loadCallback }); } }, // 分页查询 loadPage: function(pageNum, options) { this.isPaging = true; this.store.loadPage(pageNum, Ext.apply({ params: this.getParams(this.lastQuery) }, options)); },复制
- 默认查询判断函数,如果没有监听事件beforequery,则根据查询字串长度小于最小字符数(配置项minChars,默认值4)则取消查询 ext-classic/src/form/field/ComboBox.js
beforeQuery: function(queryPlan) { var me = this; if (me.fireEvent('beforequery', queryPlan) === false) { queryPlan.cancel = true; } else if (!queryPlan.cancel) { if (queryPlan.query.length < me.minChars && !queryPlan.forceAll) { queryPlan.cancel = true; } } return queryPlan; }复制
相关推荐
- ExtJs七(ExtJs Mvc创建ViewPort) 前言在4.1的时候,要先创建一个扩展于Ext.app.Application的类,然后用create创建它的实例来开始应用程序的。而在4.1.1,则可直接调用application方法开始执行应用程序,简化了。调用application方法,其参数是一个配置对象,主要配置项有以下三个:name:用来…
- 3DMAX提示和技巧 本主题标识使用 Civil View 的一些重要提示和技巧。常规使用屏幕分辨率至少为 1280x1024 的 Civil View。低于此分辨率时,一些面板将占用过多屏幕空间。 将视口设置为线框显示以达到最佳性能。 要尽可能简化用户界面,请在单个视口中工作并关闭 3ds Max 命令面…