ExtJS 5:复杂网格数据 - 设置列编辑器值

ExtJS 5: Complex grid data - set column editor value

我有 "complex" 数据——这意味着我的数据中有关联——我正试图在我的网格中使用这些关联。我根据一些数据创建了列,因为数据嵌套在一个数组中,所以我为每一列设置了一个渲染器……我还设置了一个编辑器。渲染器工作正常,但设置编辑器的值并不像我想象的那样有效。这是我的代码(和 Fiddle):

Ext.application({
  name : 'Fiddle',
  launch : function() {
    Ext.define('Phone', {
      extend: 'Ext.data.Model',
      fields: [
        {name: 'phone', type: 'int'},
        {name: 'type', type: 'string'}
      ]
    });
    Ext.define('Person', {
      extend: 'Ext.data.Model',
      fields: [
        {name: 'name', type: 'string'}
      ],
      hasMany: [
        {associationKey: 'phones', model: 'Phone', name: 'getPhonesStore'}
      ]
    });
    var beforeEdit = function(editor, context, eOpts) {
      var grid = context.grid;
      var record = context.record;
      if (grid && record) {
          var phonesStore = record.getPhonesStore();
          var columns = grid.columns;
          if (columns && phonesStore) {
              for (var i = 1; i < columns.length; i++) {
                  var column = columns[i];
                  if (column) {
                      var editor = column.getEditor();
                      if (editor) {
                          alert(phonesStore.getAt(i - 1).get('phone'));
                          editor.setValue(phonesStore.getAt(i - 1).get('phone'));
                      }
                  }
              }
          }
      }
    };
    Ext.define('MyView', {
      extend: 'Ext.grid.Panel',
      store: Ext.create('Ext.data.Store', {
        model: 'Person',
        proxy: {
          type: 'memory'
        },
        data: [
          {name: 'blah', phones: [{phone: 123456789, type: 'Home'}, {phone: 9999999999, type: 'Cell'}]},
          {name: 'bleh', phones: [{phone: 222222222, type: 'Home'}, {phone: 1111111111, type: 'Cell'}]}
        ]
      }),
      plugins: [
        {ptype: 'rowediting', clicksToEdit: 1, listeners: {beforeedit: beforeEdit}}
      ],
      height: 300,
      width: 400,
      initComponent: function() {
        var store = this.getStore();
        if (store) {
          var firstRecord = store.first();
          if (firstRecord) {
            var phonesStore = firstRecord.getPhonesStore();
            if (phonesStore) {
              var columns = [{
                xtype: 'gridcolumn',
                dataIndex: 'name',
                text: 'Name',
                editor: {
                  xtype: 'textfield',
                  hideTrigger: true
                }
              }];
              phonesStore.each(function(phoneRec) {
                columns.push({
                  xtype: 'gridcolumn',
                  text: phoneRec.get('type'),
                  renderer: this.phoneRenderer,
                  editor: {
                    xtype: 'numberfield',
                    hideTrigger: true
                  }
                });
              }, this);
              this.columns = columns;
            }
          }
        }
        this.callParent();
      },
      phoneRenderer: function(value, metaData, record, rowIndex, colIndex) {
        return record.getPhonesStore().getAt(colIndex - 1).get('phone');
      }
    });
    Ext.create('MyView', {
      renderTo: Ext.getBody()
    });
  }
});

我总共有 3 列...NameHomeCell。现在您可能在想,为什么我不只使用 Cell 和 Home 对象而不是 phones 数组……好吧,这不是我想要做的,因为我认为这不是方法正确构造此数据。无论如何,我在初始化网格时创建了这两个额外的列。

问题出在我为 "Home" 和 "Cell" 列设置的编辑器上...因为我使用的是嵌套数据并且没有合适的数据索引,当编辑器呈现,它对编辑器有一个空值。所以我想尝试利用 beforeedit 事件,我可以获得我的值,但不幸的是,我似乎无法设置编辑器的值,因为我假设 startEdit 方法有一些诡计.

你会看到,当你点击一行时,它会提醒我想在它们的编辑器中设置的 Home 和 Cell 值,但是对编辑器使用 setValue 不起作用......有没有人有任何关于如何实现这一目标的见解?

我能够在单击行时使用 setEditor 方法(在列上)解决此问题:

Ext.application({
  name : 'Fiddle',
  launch : function() {
    Ext.define('Phone', {
      extend: 'Ext.data.Model',
      fields: [
        {name: 'phone', type: 'int'},
        {name: 'type', type: 'string'}
      ]
    });
    Ext.define('Person', {
      extend: 'Ext.data.Model',
      fields: [
        {name: 'name', type: 'string'}
      ],
      hasMany: [
        {associationKey: 'phones', model: 'Phone', name: 'getPhonesStore'}
      ]
    });
    var beforeEdit = function(editor, context, eOpts) {
      var grid = context.grid;
      var record = context.record;
      if (grid && record) {
          var phonesStore = record.getPhonesStore();
          var columns = grid.getView().getGridColumns();
          if (columns && phonesStore) {
              for (var i = 1; i < columns.length; i++) {
                  var column = columns[i];
                  if (column) {
                      column.setEditor({
                          xtype: 'numberfield',
                          hideTrigger: true,
                          value: phonesStore.getAt(i - 1).get('phone')
                      });
                  }
              }
          }
      }
    };
    Ext.define('MyView', {
      extend: 'Ext.grid.Panel',
      store: Ext.create('Ext.data.Store', {
        model: 'Person',
        proxy: {
          type: 'memory'
        },
        data: [
          {name: 'blah', phones: [{phone: 123456789, type: 'Home'}, {phone: 9999999999, type: 'Cell'}]},
          {name: 'bleh', phones: [{phone: 222222222, type: 'Home'}, {phone: 1111111111, type: 'Cell'}]}
        ]
      }),
      plugins: [
        {ptype: 'rowediting', clicksToEdit: 1, listeners: {beforeedit: beforeEdit}}
      ],
      height: 300,
      width: 400,
      initComponent: function() {
        var store = this.getStore();
        if (store) {
          var firstRecord = store.first();
          if (firstRecord) {
            var phonesStore = firstRecord.getPhonesStore();
            if (phonesStore) {
              var columns = [{
                xtype: 'gridcolumn',
                dataIndex: 'name',
                text: 'Name'
              }];
              phonesStore.each(function(phoneRec) {
                columns.push({
                  xtype: 'gridcolumn',
                  text: phoneRec.get('type'),
                  renderer: this.phoneRenderer
                });
              }, this);
              this.columns = columns;
            }
          }
        }
        this.callParent();
      },
      phoneRenderer: function(value, metaData, record, rowIndex, colIndex) {
        return record.getPhonesStore().getAt(colIndex - 1).get('phone');
      }
    });
    Ext.create('MyView', {
      renderTo: Ext.getBody()
    });
  }
});