ExtJS4.2表格Grid嵌套(内部Grid)

wangcl011 2014-08-28

前文ExtJS4.2 Grid嵌套实例中讲解了如何在表格Grid中嵌套Grid,即外部Grid中每行分别展现为不同的内部Grid,比如常见的费用报销业务,费用类别有往返车费和住宿费,其中往返车费需要填写往返类型、交通工具、费用日期、出发地、目的地和金额,住宿费只需填写入住日期、离开日期、单价和金额,在一个表格中包含多种费用类别,每个费用类别下又有多条明细,所需实现的业务场景图片如:


在线演示  /  示例代码

由于前文未采用MVC模式来组织代码,代码可读性不强,本文将在前文基础上按照MVC模式来重新实现该业务场景,以供有需求的朋友参考学习。

外部表格Grid
外部表格Grid主要采用Ext.grid.plugin.RowExpander插件来实现在行记录里展示内部Grid,需设置ptype='rowexpander',并指定rowBodyTpl,同时pluginId设为'rowExpander'(后续需通过pluginId来获取),代码如下:

  1. Ext.define('Itdatum.view.UserList' ,{
  2.     extend: 'Ext.grid.Panel',
  3.     alias : 'widget.userlist',
  4.                
  5.     border : false,
  6.                         columnLines : true,
  7.                         columns : [ {
  8.                                 align : 'left',
  9.                                 dataIndex : 'feeitmtyp',
  10.                                 exportable : true,
  11.                                 header : '费用类别',
  12.                                 id : 'fituitag12',
  13.                                 menuDisabled : true,
  14.                                 renderer : renderFeeItemType,
  15.                                 style : 'text-align:center;',
  16.                                 width : 200
  17.                         }, {
  18.                                 align : 'left',
  19.                                 dataIndex : 'rbmfndnam',
  20.                                 exportable : true,
  21.                                 hidden : true,
  22.                                 id : 'fituitag13',
  23.                                 menuDisabled : true,
  24.                                 style : 'text-align:center;',
  25.                                 width : 80
  26.                         }, {
  27.                                 align : 'left',
  28.                                 dataIndex : 'remark',
  29.                                 exportable : true,
  30.                                 flex : 1,
  31.                                 header : '备注',
  32.                                 id : 'fituitag14',
  33.                                 menuDisabled : true,
  34.                                 style : 'text-align:center;',
  35.                                 width : 150
  36.                         }, {
  37.                                 align : 'right',
  38.                                 dataIndex : 'rbmtot',
  39.                                 exportable : true,
  40.                                 header : '金额',
  41.                                 id : 'fituitag15',
  42.                                 menuDisabled : true,
  43.                                 style : 'text-align:center;',
  44.                                 summaryType : 'sum',
  45.                                 width : 100
  46.                         }, {
  47.                                 align : 'left',
  48.                                 dataIndex : 'rbmbeltyp',
  49.                                 exportable : true,
  50.                                 hidden : true,
  51.                                 id : 'fituitag16',
  52.                                 menuDisabled : true,
  53.                                 style : 'text-align:center;',
  54.                                 width : 80
  55.                         }, {
  56.                                 align : 'center',
  57.                                 exportable : false,
  58.                                 header : '操作',
  59.                                 id : 'actioncolumn17',
  60.                                 items : [ {
  61.                                         handler : deleteFeeItemType,
  62.                                         iconCls : 'delete-default',
  63.                                         id : 'button18',
  64.                                         tooltip : '删除',
  65.                                         xtype : 'button'
  66.                                 } ],
  67.                                 menuDisabled : true,
  68.                                 style : 'text-align:center;',
  69.                                 width : 80,
  70.                                 xtype : 'actioncolumn'
  71.                         } ],
  72.                         fbar : [ {
  73.                                 handler : doSubmit,
  74.                                 iconCls : 'submit-default',
  75.                                 id : 'bt_submit',
  76.                                 text : '保存',
  77.                                 xtype : 'button'
  78.                         }, {
  79.                                 iconCls : 'reset-default',
  80.                                 id : 'button11',
  81.                                 text : '重置',
  82.                                 xtype : 'button'
  83.                         } ],
  84.                         features : [ {
  85.                                 ftype : 'summary',
  86.                                 id : 'summary19'
  87.                         } ],
  88.                         forceFit : false,
  89.                         id : 'feeGrid',
  90.                         loadMask : true,
  91.                         plugins : [ {
  92.                                 pluginId : 'rowExpander',
  93.                                 ptype : 'rowexpander',
  94.                                 rowBodyTpl : [
  95.                                         '<div id="{feeitmtyp}">',
  96.                                         '</div>'
  97.                                 ]
  98.                         } ],
  99.                         selType : 'rowmodel',
  100.                         sortableColumns : false,
  101.                         store : 'FeeGridStore',
  102.                         stripeRows : true,
  103.                         tbar : [ {
  104.                                 displayField : 'rbmfndnam',
  105.                                 editable : false,
  106.                                 fieldLabel : '添加费用类别',
  107.                                 hiddenName : 'feeitmtyp',
  108.                                 id : 'feeitmtyp',
  109.                                 labelStyle : 'text-align:right',
  110.                                 listeners : {
  111.                                         'select' : selectFeeItemType
  112.                                 },
  113.                                 name : 'feeitmtyp',
  114.                                 repeatTriggerClick : true,
  115.                                 store : createStore(),
  116.                                 triggerAction : 'all',
  117.                                 valueField : 'rbmfndcod',
  118.                                 xtype : 'combo'
  119.                         } ],
  120.                         title : '费用报销明细',
  121.                         viewConfig : {
  122.                                 enableTextSelection : true
  123.                         },
  124.                
  125.     initComponent: function() {
  126.                         
  127.         this.callParent(arguments);
  128.     }
  129. });


监听Grid.view的expandBody和collapsebody事件

同时监听Grid.store的add事件,即新增一种费用类别时,自动展开该费用类别的内部Grid。

  1. Ext.define('Itdatum.controller.UserController', {
  2.     extend: 'Ext.app.Controller',
  3.                
  4.                 views: [
  5.         'UserList','UserEdit'
  6.     ],
  7.    
  8.     stores: [
  9.         'UserStore','FeeGridStore','WfcfGridStore','CcbtGridStore','SnjtfGridStore','ZsfGridStore'
  10.     ],
  11.    
  12.     models: ['UserModel','FeeGridModel','WfcfInnerModel','CcbtInnerModel','SnjtfInnerModel','ZsfInnerModel'],
  13.                
  14.     init: function() {
  15.         this.control({
  16.             'viewport > userlist': {
  17.                 itemdblclick: this.editUser
  18.             },
  19.             'useredit button[action=save]': {
  20.                 click: this.updateUser
  21.             },
  22.             'userlist': {
  23.                 afterrender: function(feeGrid){//侦听userlist渲染  
  24.                      feeGrid.view.on('expandBody', function (rowNode, record, expandRow, eOpts) {
  25.                           var rbmbeltyp=record.get('rbmbeltyp');
  26.                           if(rbmbeltyp==='WFCF') {
  27.                               displayWfcfInnerGrid(record);
  28.                            }else if(rbmbeltyp==='SNJTF') {
  29.                                displaySnjtfInnerGrid(record);
  30.                            }else if(rbmbeltyp==='ZSF') {
  31.                                displayZsfInnerGrid(record);
  32.                            }else if(rbmbeltyp==='CCBT') {
  33.                                displayCcbtInnerGrid(record);
  34.                            }
  35.                      });
  36.                                                                   
  37.                      feeGrid.view.on('collapsebody', function (rowNode, record, expandRow, eOpts) {
  38.                            var rbmbeltyp=record.get('rbmbeltyp');
  39.                            if(rbmbeltyp==='WFCF') {
  40.                                destroyWfcfInnerGrid(record);
  41.                            }else if(rbmbeltyp==='SNJTF') {
  42.                                destroySnjtfInnerGrid(record);
  43.                            }else if(rbmbeltyp==='ZSF') {
  44.                                destroyZsfInnerGrid(record);
  45.                            }else if(rbmbeltyp==='CCBT') {
  46.                                destroyCcbtInnerGrid(record);
  47.                            }
  48.                      });
  49.                                                                   
  50.                      feeGrid.getStore().on('add',function( store, records, index, eOpts){
  51.                            //alert(records.length);
  52.                            feeGrid.getPlugin('rowExpander').toggleRow(index,records[0]);
  53.                      });
  54.                 }  
  55.             }
  56.         });
  57.     },
  58.    
  59.     editUser: function(grid, record) {
  60.         alert('Edit User');
  61.         //console.log('Double clicked on ' + record.get('name'));
  62.         
  63.         var view = Ext.widget('useredit');
  64.         view.down('form').loadRecord(record);
  65.     },
  66.    
  67.     updateUser: function(button) {
  68.         alert('UpdateUser');
  69.         //console.log('clicked the Save button');
  70.     },
  71.     onPanelRendered: function() {
  72.         //console.log('The panel was rendered');
  73.     }
  74. });

其他代码较多,不一一贴出来了,请自行研究在线实例

Global site tag (gtag.js) - Google Analytics