EXTJS Combo 集问题
Posted
技术标签:
【中文标题】EXTJS Combo 集问题【英文标题】:EXTJS Combo set problem 【发布时间】:2010-08-16 06:55:57 【问题描述】:我在输入表单中使用组合时遇到了一个有趣的问题。我的表单包含从 json 存储中获取数据的组合。添加新记录时它工作正常,但是当打开表单以编辑现有记录时,有时 id 显示为选中而不是其值(例如:有 5 而不是“apple”)。我认为它会在完成加载组合之前尝试设置值。
我检查了组合存储计数,它返回零,这意味着在加载组合之前完成了选择。我尝试在加载事件中设置值并触发选择事件,但它不起作用 当我在加载存储时重新选择另一条记录时效果很好
我也看到了这个帖子,但它没有给出可行的答案 ExtJS combo setting problem
有没有设置它的文本?
谁能给我正确的解决方案?
【问题讨论】:
能否请您发布一些组合框的示例代码以及您如何加载/绑定返回值? 【参考方案1】:您是否使用标准的 ExtJs 方法setValue
来设置组合框的值?
检查您是否在 Ext.onReady(...); 中设置了值
或者,如果您通过 ajax 加载值,您可以使用带有回调的更新方法作为第三个参数(参见 http://dev.sencha.com/deploy/dev/docs/ -> ComboBox)
【讨论】:
onReady() 是不够的,因为即使 dom 已经准备好,combobox 的 store 也无法加载。【参考方案2】:为什么模式设置为本地而不是远程?您是否使用 FireBug 确保从 ASP 服务发送的数据格式正确?
我有点不清楚您对这两款商品的期望: valuefield: 'PartyTypeId' displayField: 'PartyType'
【讨论】:
【参考方案3】:我已经为此奋斗了一段时间,终于受够了。在加载任何组合之前在某处添加此 hack(不必在文档准备好之后)
Ext.form.ComboBox.prototype.nativeSetValue = Ext.form.ComboBox.prototype.setValue;
Ext.form.ComboBox.prototype.setValue=function(v)
var combo = this;
if(this.valueField)
var r = this.findRecord(this.valueField, v);
if (!r)
var data =
data[this.valueField] = v;
this.store.load(
params:data,
callback:function()
combo.nativeSetValue(v);
)
else return combo.nativeSetValue(v);
else combo.nativeSetValue(v);
这基本上将检查您的值是否在您的商店中,如果没有,请使用 valueField = value 进行回调,然后再次尝试设置。您只需要确保您的服务器端处理程序为搜索查找“查询”并为加载查找关键字段
【讨论】:
【参考方案4】:有时它会显示为 id,因为您的代码中有一个 race condition。其实如果store已经加载了,就会显示显示值,否则就是id。
我在自己的代码中对此进行了测试。存储的加载速度比 Ajax 调用检索初始化值的速度快得多(因为我对第一次调用进行了 memcached)。由于首先加载了商店,因此使用 Id 调用 setValue() 效果很好。
但是,当我试图故意减慢存储加载 Ajax 调用时,只显示 id 而不是显示值。所以我看到答案告诉你要解决这个问题,你必须在 ComboBox 中使用 autoLoad: true。使用 autoLoad 很好,但还不够。您要确保在设置值时,商店已经被加载。为此,只需在 store 的 load 事件上放置一个监听器:
var dataStore = new Ext.data.JSonStore(
url: 'your-url',
root: 'records',
fields: ['id', 'name'],
autoLoad: true,
listeners:
load: function ()
app.initForm(); //here the name of the function setting form values
);
有了这个事件,这两种情况都可以正常工作。
为了防止在第一次运行后 ComboBox 触发新的 load() 事件时重新加载数据,我正在检查是否在 app.initForm() 中设置了值
app.initForm = function ()
var customerField = Ext.getCmp('formName').getForm().findField('idCustomer');
if (customerField.getValue !== '')
return; //skipping init, form already filled
//Ajax Call here
;
【讨论】:
【参考方案5】:var partyType_store = new Ext.data.Store(
autoLoad: false,
autoDestroy: true,
// Note that I have renamed the web service proxy class
proxy: new Ext.data.HttpProxy(
url: accounts.webService + '/GetType',
// ASP.NET WebService call in GET format
headers:
'Content-type': 'application/json'
),
fields: ['AccountTypeId', 'AccountTypeName'],
listeners
load: function()
Ext.getCmp('cmbPartyType').setValue(Ext.getCmp("txtId").getValue());
Ext.getCmp('cmbPartyType').fireEvent("select");
,
// Combo is defined as
xtype: 'combo',
width: 150,
fieldLabel: 'Party Type',
name: 'PartyType',
id: 'accounts-cmbPartyType',
store: partyType_store,
displayField: 'PartyType',
valueField: 'PartyTypeId',
hiddenName: 'PartyTypeId',
mode: 'local', // important property when using store
typeAhead: true,
triggerAction: 'all',
selectOnFocus: true,
allowBlank: true,
forceSelection: true
我在事件说按钮点击事件上加载组合商店
Ext.getCmp('cmbPartyType').getStore().load(); //this calls combo load event
如果我在 store 中设置 autoLoad=true 效果很好 但实际上我不想在用户按下按钮之前加载商店以减少流量
【讨论】:
也许你的组合需要使用lazyRender=true。我认为您应该将此信息添加到您的原始问题中,而不是作为答案(我可能错了,我对 SO 很陌生)。以上是关于EXTJS Combo 集问题的主要内容,如果未能解决你的问题,请参考以下文章