ExtJs - 网格编辑器中远程存储组合框的渲染器

时间:2014-06-01 16:11:58

标签: extjs combobox grid editor extjs4.2

我知道这已被一次又一次地问过,但我找不到一个可靠的答案作为这类问题的标准。

在网格内部有一个编辑器之前,许多人已经完成了这一工作,该网格是一个使用数据库远程存储的组合框。现在假设数据库中有一个包含50,000条记录的表。 组合框仅加载前15个。当我在这15个之间选择一个记录时,一切都显示正常。要呈现displayField而不是valueField,我使用以下函数

  renderCombobox : function(value, metaData, record, rowIndex, colIndex, store, view, isNewRow){      
      var me      = this,
          columns = me.columns,
          editor, editorStore, editorIndex, displayField, display, rec;

    for(var i=0,j=columns.length;i<j;i++){          
      if(columns[i].getEditor){
          editor = columns[i].getEditor(record);
          if(editor.xtype === 'combobox'){
              editorStore   = editor.getStore().load();
              editorIndex   = editorStore.findExact(editor.valueField, value);
              displayField = editor.displayField;
          }
      }
    }      
    if(editorIndex != -1){
        rec = editorStore.getAt(editorIndex);
        if(rec && rec.get(displayField)){
            display = rec.get(displayField);
        }               
    }      
    return display;        
}

问题是以下情况。

如果我提前输入,我可以找到不在这15条记录之间的记录。例如记录42,300。我选择它,目前一切都好。 现在如果我点击网格中另一个编辑器上的另一个字段(即datefield)渲染器 组合框的函数返回undefined,因为它试图找到具有商店中不存在的记录42,300的值的记录。调试器说该商店只包含前15条记录。

我错过了任何配置吗?商店需要一个限制。我不能一次从数据库中带来50,000条记录。

2 个答案:

答案 0 :(得分:2)

我认为此示例完全符合您的要求:http://extjs.eu/ext-examples/#combo-in-grid

答案 1 :(得分:0)

令人敬畏的Saki的文章给了我解决这个任务的线索。

您不需要任何渲染器,只需为您的组合添加一个包含所有键值对的附加商店,然后添加&#39;编辑&#39;事件到网格。

在这里。

您的其他远程商店:

Ext.define('crm.store.BillAdTarifsStore', {
    extend      : 'Ext.data.Store',
    storeId     : 'BillAdTarifsStore',
    requires    : 'crm.model.BillAdTarifsModel',
    model       : 'crm.model.BillAdTarifsModel',
    autoLoad    : true 
});

它的模型:

Ext.define('crm.model.BillAdTarifsModel', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'id',        type: 'int'},
        { name: 'VarName',   type: 'string' }
    ],
    proxy   : {
        type    : 'ajax',
        url     : AjaxUrl,
        reader  : {
            type            : 'json',
            idProperty      : 'id',
            root            : 'data',
            totalProperty   : 'total',
            successProperty : 'success',
            messageProperty : 'message'
        },
        extraParams  : {
            Action   : 'DataRequest',
            DataType : 'GetBillAdTarifs'
        }
    }
});

网格配置:

plugins: [
    Ext.create('Ext.grid.plugin.CellEditing', {
        clicksToEdit: 1
    })
],
listeners: {
    // this event will change valueField in cell to the displayField (after choosing combo item)
    edit: function(e, eOpts) {
        // eOpts.rowIdx - is the index of row with clicked combo
        var SelectedComboId = Number(Ext.getCmp('ObjectsGrid').getStore().getAt( eOpts.rowIdx ).get('YourGridColumnName'));
        console.log( 'SelectedComboId: '+SelectedComboId );

        if(Number(SelectedComboId) > 0) {
            // ComboItemObj - get field name by index from additional store
            var ComboItemObj = Ext.data.StoreManager.lookup('BillAdTarifsStore').getById(SelectedComboId);
            if ( typeof ComboItemObj.data.id !== null && Number(ComboItemObj.data.id)>0 ) {
                // real combo item is chosen, set field name
                    Ext.getCmp('ObjectsGrid').getStore().getAt(eOpts.rowIdx).set('TrfCianBig',ComboItemObj.data.VarName);
            }
        }
    }

列配置如下所示:

editor  : new Ext.form.field.ComboBox({
    triggerAction : 'all',
    forceSelection: false,
    editable    : false,
    allowBlank  : true,
    displayField: 'VarName',
    valueField  : 'id',
    store       : Ext.data.StoreManager.lookup('BillAdTarifsComboStore'),
        listeners: {
                 'change': function(comp, newValue, oldValue, eOpts) {
                               // Selected combo id value
                               var ComboValue  = comp.getValue();
                                // save data by some Ext.Ajax.request
                                },
                 click: {
                            // you can preload combo store with specifig parameters
                            element: 'el', 
                            fn  : function (store, operation, eOpts) {
                                .....
                                ComboStore.load({
                                        params: {
                                            SomeId : SomeParam
                                        }
                                    });