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 集问题的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS Combo 默认值返回 null

Extjs Combo - 如何使用 GetForm().load 将值加载到组合

ExtJs中Combo组件默认选中

Extjs3 Combo实现百度搜索查询

extjs--combo动态获取数据

Extjs Combo - 为啥在我没有创建表单时加载组合包含组合