简体   繁体   English

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

[英]How to display a property in a combobox within a grid with CellEditing plugin and save a complete JSON in ExtJS 4.2

I am trying to display a property from a JSON received from a server in a combobox within a grid with cell editing. 我正在尝试使用单元格编辑在网格内的组合框中显示从服务器接收的JSON的属性。 When the user selects an option I want to display the same property, but when the user saves the grid, I want the complete JSON to be sent to the server (not just the display value nor the id field). 当用户选择一个选项时,我想显示相同的属性,但是当用户保存网格时,我希望将完整的JSON发送到服务器(不仅仅是显示值或id字段)。

This is what I have so far (available here http://jsfiddle.net/apater39/do0xg4r1/ ): 这是我到目前为止的内容(可在此处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()
});

If I use valueField 'id' then when the user chooses an option from the combobox the id is displayed (instead of the displayField). 如果我使用valueField'id',则当用户从组合框中选择一个选项时,将显示ID(而不是displayField)。

The JSON that I would like to be sent is this: 我想发送的JSON是这样的:

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

Thanks for the help. 谢谢您的帮助。

UPDATE: 更新:

Based on the suggestion of Jorge Ramon, I arrived at a solution (see http://jsfiddle.net/apater39/8opsqg5s/ ). 根据Jorge Ramon的建议,我得出了一个解决方案(请参阅http://jsfiddle.net/apater39/8opsqg5s/ )。 The important thing is to to listen to the edit event of cellediting pluging, and then find the selected record of the combo and set the corresponding property. 重要的是侦听cellediting插入的edit事件,然后找到该组合的选定记录并设置相应的属性。

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()
});

The JSON sent becomes: 发送的JSON变为:

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

You will need to change several stuff in your code to achieve want you want to do... 您将需要更改代码中的几项内容,以实现想要执行的操作...

First is that your are trying to work with association (Person contains a State) but you are not declaring the association. 首先是您正在尝试使用关联(人员包含一个州),但您并未声明关联。 To declare your association correctly, I suggest to read this : https://stackoverflow.com/a/16492938/3494608 And also deeply suggest to read this : http://extjs-tutorials.blogspot.fr/2012/05/extjs-hasmany-relationships-rules.html 为了正确声明您的关联,我建议您阅读以下内容: https : //stackoverflow.com/a/16492938/3494608并强烈建议您阅读以下内容: http : //extjs-tutorials.blogspot.fr/2012/05/extjs -hasmany-relationships-rules.html

Afterward, you will need to see how to correctly set your association because your combobox here only set a value (the id of the model corresponding to the select state) and not the record itself. 之后,您将需要查看如何正确设置关联,因为此处的组合框仅设置一个值(与选择状态相对应的模型的ID),而不是记录本身。

And then, you will see how to send the complete model with association. 然后,您将看到如何发送带有关联的完整模型。 I did not did it myself within Ext4.2 but you'll find some lecture in google (Key words: extjs save nested model). 我不是在Ext4.2中自己做的,但是您会在google中找到一些讲座(关键字:extjs保存嵌套模型)。 Found this first : https://www.sencha.com/forum/showthread.php?274778-Add-new-record-of-Model-that-contains-nested-Model 首先找到这个: https : //www.sencha.com/forum/showthread.php?274778-Add-new-record-of-Model-that-c​​ontains-nested-Model

I don't have a "all-in-one" solution because working with association is unfortunately a though work with ExtJs (less with ExtJs 5+ but still...) 我没有“多合一”解决方案,因为不幸的是,与关联的工作是与ExtJ一起工作(虽然与ExtJs 5+相比工作较少,但仍然...)

Good luck! 祝好运!

You want to have the combo editor set like this example: 您想要像以下示例那样设置组合编辑器:

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

Then, use the celleditor plugin: 然后,使用celleditor插件:

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

And handle the plugin's edit event: 并处理插件的edit事件:

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.     
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM