如何使用CellEditing插件在网格中的组合框中显示属性并在ExtJS 4.2中保存完整的JSON

时间:2016-02-27 15:15:12

标签: extjs extjs4.2

我正在尝试使用单元格编辑从网格中的组合框中的服务器接收的JSON中显示属性。当用户选择我希望显示相同属性的选项时,但是当用户保存网格时,我希望将完整的JSON发送到服务器(不仅仅是显示值和id字段)。

这是我到目前为止(可在http://jsfiddle.net/apater39/do0xg4r1/获得):

Ext.define('NS.model.State', {
  extend: 'Ext.data.Model',
  fields: [{
    name: 'id',
    type: 'int'
  }, {
    name: 'name',
    type: 'string'
  }]
});
Ext.define('NS.store.State', {
  extend: 'Ext.data.Store',
  model: 'NS.model.State',
  data: [{
    "id": 1,
    "name": "Alabama"
  }, {
    "id": 2,
    "name": "Alaska"
  }, {
    "id": 3,
    "name": "Arizona"
  }]
});

Ext.define('NS.model.Person', {
  extend: 'Ext.data.Model',
  fields: [{
    name: 'id',
    type: 'int'
  }, {
    name: 'firstName',
    type: 'string'
  }, {
    name: 'state',
    type: 'NS.model.State'
  }]
});

Ext.define('NS.store.Grid', {
  extend: 'Ext.data.Store',
  model: 'NS.model.Person',
  data: {
    'items': [{
      'id': 1,
      "firstName": "Lisa",
      "state": null
    }, {
      'id': 2,
      "firstName": "Bart",
      "state": null
    }, {
      'id': 3,
      "firstName": "Homer",
      "state": null
    }, {
      'id': 4,
      "firstName": "Marge",
      "state": null
    }]
  },
  proxy: {
    type: 'memory',
    reader: {
      type: 'json',
      root: 'items'
    }
  }
});

Ext.create('Ext.grid.Panel', {
  title: 'Simpsons',
  store: Ext.create('NS.store.Grid'),
  columns: [{
    header: 'First Name',
    dataIndex: 'firstName',
    flex: 1,
    editor: 'textfield'
  }, {
    header: 'State',
    dataIndex: 'state',
    flex: 1,
    editor: {
      xtype: 'combobox',
      store: Ext.create('NS.store.State'),
      queryMode: 'local',
      displayField: 'name',
      valueField: 'id'
    }
  }],
  selType: 'cellmodel',
  plugins: [{
    ptype: 'cellediting',
    clicksToEdit: 2
  }],
  height: 150,
  width: 200,
  renderTo: Ext.getBody()
});

如果我使用valueField' id'然后当用户从组合框中选择一个选项时,会显示id(而不是displayField)。

我想发送的JSON是:

{
  "id": 1,
  "firstName": "Lisa",
  "state": 
   {
     "id": 1,
     "name": "Alabama"
   }
}

感谢您的帮助。

更新:

根据Jorge Ramon的建议,我找到了一个解决方案(见http://jsfiddle.net/apater39/8opsqg5s/)。重要的是要收听cellediting pluging的编辑事件,然后找到所选的组合记录并设置相应的属性。

var gridPanel = Ext.create('Ext.grid.Panel', {
  title: 'Simpsons',
  store: gridStore,
  columns: [{
    header: 'First Name',
    dataIndex: 'firstName',
    flex: 1,
    editor: 'textfield'
  }, {
    header: 'State',
    dataIndex: 'state',
    flex: 1,
    editor: {
      xtype: 'combobox',
      store: Ext.create('NS.store.State'),
      displayField: 'name',
      valueField: 'name',
      editable: false,
      queryMode: 'local',
      forceSelection: true,
      triggerAction: 'all',
      selectOnFocus: true,
      allowBlank: false
    },
    renderer: function(value) {
      return value.name;
    }
  }],
  selType: 'cellmodel',
  plugins: [{
    ptype: 'cellediting',
    clicksToEdit: 2,
    listeners: {
      edit: function(editor, ctx, eOpts) {
        var vendorColIdx = 1;
        if (vendorColIdx === ctx.colIdx) {
          var combo = ctx.grid.columns[vendorColIdx].getEditor(ctx.record);
          var vendorRecord = combo.findRecord('name', ctx.record.get('state'));
          ctx.record.set('state', vendorRecord.data);
        }
        ctx.grid.getStore().sync();
      }
    }
  }],
  height: 250,
  width: 200,
  renderTo: Ext.getBody()
});

发送的JSON变为:

{"id":1,"firstName":"Lisa","state":{"id":2,"name":"Alaska"}}

2 个答案:

答案 0 :(得分:2)

您需要更改代码中的几个内容才能达到想要的目的......

首先,您正在尝试使用关联(Person包含一个State)但您没有声明关联。 要正确声明您的关联,我建议您阅读:https://stackoverflow.com/a/16492938/3494608 并且还深刻建议阅读:http://extjs-tutorials.blogspot.fr/2012/05/extjs-hasmany-relationships-rules.html

之后,您需要了解如何正确设置关联,因为此处的组合框仅设置一个值(与选择状态对应的模型的ID)而不是记录本身。

然后,您将看到如何发送带关联的完整模型。我没有在Ext4.2中自己做过,但你会在谷歌找到一些讲座(关键词:extjs保存嵌套模型)。 首先找到这个:https://www.sencha.com/forum/showthread.php?274778-Add-new-record-of-Model-that-contains-nested-Model

我没有“一体化”的解决方案,因为与关联工作很遗憾,虽然使用ExtJs(使用ExtJs 5+但仍然......)

祝你好运!

答案 1 :(得分:1)

您希望将组合编辑器设置为此示例:

editor: {
    xtype: 'combobox',
    store: 'Vendors',
    displayField: 'name',
    valueField: 'name',
    editable: false,
    queryMode: 'remote',
    forceSelection: true,
    triggerAction: 'all',
    selectOnFocus: true,
    allowBlank: false
}

然后,使用celleditor插件:

plugins: {
   ptype: 'cellediting',
   clicksToEdit: 1,
   listeners: {
       edit: 'onGridEditorEdit'
   }
}

并处理插件的编辑事件:

onGridEditorEdit: function (editor, ctx, eOpts) {
    var vendorColIdx = 2;
    if (vendorColIdx === ctx.colIdx + 1) {
        var combo = ctx.grid.columns[vendorColIdx].getEditor(ctx.record);
        var vendorRecord = combo.findRecord('name', ctx.record.get('vendorName'));
        ctx.record.set('vendorId', vendorRecord.get('id'));
    }
    ctx.grid.getStore().sync();  // Force a post with the updated data.     
}