ExtJS远程ComboBox请求Payload异常及自定义需求咨询
ExtJS ComboBox 请求Payload格式修正方案
问题现状
现有ExtJS ComboBox及对应Store配置如下:
ComboBox配置
Ext.define('Dropchop.components.form.fields.BaseUnitCombobox', { extend: 'Ext.field.ComboBox', alias: 'widget.base-unit-combobox', store: { type: 'base-units-store' }, name: 'baseUnit', queryMode: 'remote', queryParam: 'name', displayField: 'name', valueField: 'id', });
Store配置
Ext.define('Dropchop.store.BaseUnitsStore', { extend: 'Ext.data.Store', alias: 'store.base-units-store', model: 'Dropchop.nutril.model.Unit', autoLoad: false, proxy: { url: Ext.manifest.api + '/public/catalog/units', type: 'ajax', startParam: '', pageParam: '', limitParam: '', paramsAsJson: true, actionMethods: { create: 'POST', read: 'POST', update: 'POST', destroy: 'POST' }, reader: { type: 'json', rootProperty: 'data', }, extraParams: { base: true } } });
当前请求Payload为:
{"base":true,"name":[null]}
需要修正为以下合法格式之一:
{"base":true,"name":[]} // 或 {"base":true} // 或 {"base":true,"name":"hello world"}
同时存在另一个问题:在Store加载前设置ComboBox的值,请求Payload仍为{"base":true,"name":[null]},未携带设置的值。
解决方案
方案1:重写ComboBox的getParams方法自定义请求参数
直接在ComboBox类中重写getParams方法,手动处理name参数的格式,避免出现[null]的情况,同时确保设置值时能正确携带参数:
Ext.define('Dropchop.components.form.fields.BaseUnitCombobox', { extend: 'Ext.field.ComboBox', alias: 'widget.base-unit-combobox', store: { type: 'base-units-store' }, name: 'baseUnit', queryMode: 'remote', queryParam: 'name', displayField: 'name', valueField: 'id', getParams: function(queryString) { var params = this.callParent(arguments); // 处理name参数:如果是[null]则改为空数组,或者直接移除;如果有有效值则转为字符串 if (params.name && Array.isArray(params.name)) { if (params.name.length === 1 && params.name[0] === null) { params.name = []; // 也可以选择移除该参数:delete params.name; } else if (params.name.length === 1) { // 单个值转为字符串 params.name = params.name[0]; } } return params; } });
方案2:在Store Proxy的beforerequest事件中修正参数
在Store的proxy上绑定beforerequest事件,在请求发送前直接修改请求的参数:
Ext.define('Dropchop.store.BaseUnitsStore', { extend: 'Ext.data.Store', alias: 'store.base-units-store', model: 'Dropchop.nutril.model.Unit', autoLoad: false, proxy: { url: Ext.manifest.api + '/public/catalog/units', type: 'ajax', startParam: '', pageParam: '', limitParam: '', paramsAsJson: true, actionMethods: { create: 'POST', read: 'POST', update: 'POST', destroy: 'POST' }, reader: { type: 'json', rootProperty: 'data', }, extraParams: { base: true }, listeners: { beforerequest: function(proxy, operation) { var params = operation.getParams(); if (params.name) { if (Array.isArray(params.name)) { if (params.name.length === 1 && params.name[0] === null) { params.name = []; // 或者删除参数:delete params.name; } else if (params.name.length === 1) { params.name = params.name[0]; } } } operation.setParams(params); } } } });
方案3:处理ComboBox的beforequery事件调整查询参数
通过beforequery事件拦截查询请求,修正查询参数,同时确保设置值时触发正确的查询:
Ext.define('Dropchop.components.form.fields.BaseUnitCombobox', { extend: 'Ext.field.ComboBox', alias: 'widget.base-unit-combobox', store: { type: 'base-units-store' }, name: 'baseUnit', queryMode: 'remote', queryParam: 'name', displayField: 'name', valueField: 'id', listeners: { beforequery: function(queryPlan) { // 修正空查询的参数 var query = queryPlan.query; if (query === null || query === '') { queryPlan.query = []; } // 当设置值后,确保查询参数携带对应值 var value = this.getValue(); if (value) { var record = this.findRecord(this.valueField, value); queryPlan.query = record ? record.get(this.displayField) : value; } return true; } } });
补充:设置ComboBox值后强制携带参数的处理
如果设置值后请求仍未携带参数,可以手动调用Store的load方法并传入自定义参数:
// 假设combo是ComboBox实例 combo.setValue('some-value-id'); var record = combo.findRecord(combo.valueField, combo.getValue()); var queryName = record ? record.get(combo.displayField) : combo.getValue(); combo.getStore().load({ params: { name: queryName, base: true } });
内容的提问来源于stack exchange,提问作者Armando
相关产品推荐
相关产品推荐

