<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length > 300) { text = text + "\r\n\n本文来自博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script><script type="text/javascript"> function StorePage() { d = document; t = d.selection ? (d.selection.type != 'None' ? d.selection.createRange().text : '') : (d.getSelection ? d.getSelection() : ''); void (keyit = window.open('http://www.365key.com/storeit.aspx?t=' + escape(d.title) + '&u=' + escape(d.location.href) + '&c=' + escape(t), 'keyit', 'scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes')); keyit.focus(); }</script>
使用extjs配合struts的MVC架构是目前流行的做法,两者的整合相当简单,只需扩展Action,直接向HttpServletResponse里写xml和json格式的内容,不再需要forward到struts指定的页面。
// 取查询结果xml和总记录个数 String xml = resultBuffer.getStringValue( CoreConsts.LIST_DATA_XML, 0 ); String records = resultBuffer.getStringValue( CoreConsts.TOTAL_COUNT, 0 ); // 替换xml中的记录个数 xml = replaceRecords( xml, records ); if ( records.equals( " 0 " ) ) xml = " <response success='false'> " + xml + " </response> " ; else xml = " <response success='true'> " + xml + " </response> " ; response.setContentType( " application/xml;charset=UTF-8 " ); PrintWriter out = null ; try ... { out = response.getWriter(); } catch ( IOException e ) ... { e.printStackTrace(); } out.write( xml );上面的java代码片端实现了一个通用的Action扩展,姑且称之为EXTJSAction,向HttpServletResponse写入 xml内容,包括(但不限于)处理结果的xml格式内容和总的记录个数(用于翻页时显示总记录个数),以及成功或失败的标记,就这么简单!
接下来要求extjs能够识别并处理EXTJSAction返回的xml内容,通常在一个Ext.form.Form里实现,请看下面的代码片段:
var fs = new Ext.form.Form( ... { labelAlign: ' right ' , labelWidth: 75 , buttonAlign: ' left ' , // reusable eror reader class defined at the end of this file errorReader: new Ext.form.XmlErrorReader() } ); fs.fieldset( ... {legend: ' 基本信息 ' } ); dsCust = new Ext.data.Store( ... { proxy: new Ext.data.HttpProxy( ... {url: ' ../getCustList.do ' } ), reader: new Ext.data.XmlReader( ... { // records will have a "customer" tag // root: 'response', record: ' table ' , totalRecords: ' records ' } ,[ ' CUSTID ' , ' CUSTSHORTNAME ' ]) } ); comboboxCust = new Ext.form.ComboBox( ... { fieldLabel: ' 客户 ' , typeAhead: true , triggerAction: ' all ' , store: dsCust, displayField: ' CUSTSHORTNAME ' , valueField: ' CUSTID ' , width: 200 , forceSelection: true , name: ' clientid ' , hiddenName: ' clientid ' , emptyText: ' 选择一个客户... ' , allowBlank: false , blankText: ' 请选择一个客户 ' , pageSize: 20 } ); fs.column( ... {width: 300 } , comboboxCust ); fs.addButton( ' 保存并新增 ' , function () ... { // 组装grid的json /**/ /* var jsonData = ""; for( i=0; i < ds.getCount(); i ++ ) { var rec = ds.getAt( i ); if ( rec.data.newRecord || rec.dirty ) { jsonData += Ext.util.JSON.encode( rec.data ) + ","; } } jsonData = jsonData.substring( 0, jsonData.length - 1 ); //alert( jsonData ) //console.info(jsonData); */ var m = ds.modified.slice( 0 ); var jsonData = " [ " ; for ( var i = 0 , len = m.length; i < len; i ++ ) ... { // alert(m[i].data["user_name"]); var ss = Ext.util.JSON.encode( m[i].data ); // alert(ss); if ( i == 0 ) jsonData = jsonData + ss; else jsonData = jsonData + " , " + ss; } jsonData = jsonData + " ] " ; // alert(jsonData); fs.submit( ... { url: " ../addSaleOrder.do " , params: ... {json:jsonData} , waitMsg: ' 正在处理,请稍候... ' , success: function (form, action ) ... { Ext.MessageBox.alert( " 销售订单! " , " 保存销售订单成功! " ); fs.reset(); ds.modified = []; // 将修改过的记录置为空,如果不清空,则修改过的数据会一直保留 ds.removeAll(); // 从grid中移去 } , failure: function ( form, action ) ... { Ext.MessageBox.alert( " 销售订单! " , " 保存销售订单失败! " ); } } ); } ); // A reusable error reader class for XML forms Ext.form.XmlErrorReader = function () ... { Ext.form.XmlErrorReader.superclass.constructor.call( this , ... { record : ' field ' , success: ' @success ' } , [ ' id ' , ' msg ' ] ); } ; Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);首先定义了一个Form,这个Form有一个XmlErrorReader,能够读取EXTJSAaction返回的xml格式,判断 EXTJSAaction处理是成功还是失败。Form被提交到../addSalesOrder.do,这是我们熟悉的struts格式,将调用到 EXTJSAction,此即是extjs和struts交互的关键!
我们还注意到上面的js代码中,Form包含一个ComBoBox,用于从下拉列表中选择客户,这个ComBoBox是分页的 (pageSize:20,会自动在ComBoBox展开后下放加翻页工具栏)。客户列表的内容同样来之于EXTJSAction, 即../getCustList.do,这就是一个通用的EXTJSAction的好处,随处可使用!
请仔细体会上面的代码,extjs和struts的整合是如此的简单!
另外,Form在提交时,将Grid的内容组装成一个json格式的字符串,是为了方便成批提交Grid中的记录,那么在服务器端如何处理这个json串中的多条记录呢?需要用到json的java类库(http://www.json.org/java/ ),代码如下:
// 保存订单明细 String json = this .getVariableSpace().getStringValue( " json " , 0 ); json = RequestUtil.iso2utf( json ); if ( json != null || json.trim().length() > 0 ) ... { JSONArray jsonArr = null ; try ... { XmlDBService xdbs = XmlDBServiceManager.getXmlDBService( Const.XMLDBSERVICE ); jsonArr = new JSONArray( json ); for ( int i = 0 ; i < jsonArr.length(); i ++ ) ... { String pmgg = jsonArr.getJSONObject( i ).getString( " PMGG " ); String unit = jsonArr.getJSONObject( i ).getString( " UNIT " ); String amount = jsonArr.getJSONObject( i ).getString( " AMOUNT " ); String price = jsonArr.getJSONObject( i ).getString( " PRICE " ); // String money = jsonArr.getJSONObject( i ).getString( "MONEY" ); String availDate = jsonArr.getJSONObject( i ).getString( " availDate " ); String sql = " insert into sorderdetail ( sorderid, itemno, goodsid, unitid, quantity, unitprice, validdate ) select " + sorderid + " , " + ( i + 1 ) + " , ' " + pmgg + " ', ( select unitid from goodsunit where goodsid = " // 取单位序号 + pmgg + " and unitname = ' " + unit + " ' ), " + amount + " , " + price + " , ' " + availDate + " ' " ; xdbs.executeDAC( sql ); } } catch ( Exception e ) ... { e.printStackTrace(); // 加处理失败标记 this .outputBuffer.get( CoreConsts.TOTAL_COUNT, 0 ).setValueWithString( " 0 " ); } }上面的java代码片段依此处理json串的多条记录,构造sql语句,将记录添加到数据库中,以json的方式处理成批提交的记录,应该是最方便的方法。
相关资源:敏捷开发V1.0.pptx