您現在的位置:首頁 >> Web開發 >> IntraWeb >> 內容

Intraweb之EasyUI篇

時間:2015/5/5 15:29:47 點擊:

  核心提示:Intraweb一直是Delphi快速開發web應用的首選工具,但自帶的控件較少,樣式比較難看,TMS與IW倒是可用,可是要收費,對于我們這些習慣用免費的用戶來說,想找個破解也比較費勁。EasyUI是基于JQuery開發的框架,內置的控件完全可以滿足我們開發一般web程序的需求,而且是免費的,用起來...
Intraweb一直是Delphi快速開發web應用的首選工具,但自帶的控件較少,樣式比較難看,TMS與IW倒是可用,可是要收費,對于我們這些習 慣用免費的用戶來說,想找個破解也比較費勁。EasyUI是基于JQuery開發的框架,內置的控件完全可以滿足我們開發一般web程序的需求,而且是免 費的,用起來也心安理得。下面我就IW如何結合EasyUI開發程序談談自己的一些心得,與大家交流一下。主要有以下幾種方法:
  一、使用模板
  在IWForm內使用模板引入做好的html文件,結合IW自身的控件進行操控。這種方法雖說比較方便,但模板也有自身的缺點,內部不支持中文引用是 一大Bug,目前IW都沒有要解決的跡像。如果一定要用模板,也有方法規避,即漢字全部用網頁轉義“&#”加漢字的十進制編碼。模板的使用有很多 文章可供參考,也不是本章的重點,不做具體講解。
  二、MVC設計模式
  IW使用MVC方式結合EasyUI設計程序,是本文的重點。我們知道IW與HTML靜態頁面的交互,可以通過javascript接口來實現,可以 使用AddToInitProc('alert("歡迎")')這樣的語句,也可以在控件的JavascriptEvent屬性內添加js語句。本文介紹 的方法完全將界面與數據處理分開,一律使用EasyUI來實現界面(完全不用IW的可視控件,數據庫控件還是需要的),數據處理交給IW后臺做。我們以開 發一個簡單的應用程序來一步步實現這些功能,同時會使用一定篇幅介紹EasyUI部分控件的使用(本文必須要有一定的javascript基礎)。
  第一步:實現登陸界面。

  首先引入以下文件,后面其它頁面也一樣這樣引用,直接貼代碼:

  1. <span style="white-space:pre">    </span><link rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css">  
  2. <link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">  
  3. <script type="text/javascript" src="easyui/jquery.min.js"></script>  
  4. <script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>  
  5. <script type="text/javascript" src="easyui/locale/easyui-lang-zh_CN.js"></script>  
   這些文件是必須引用的,easyui.css是自帶的樣式,icon.css是使用中的各種圖標,easyui-lang-zh_CN.js是漢化文件(EasyUI對中文支持還是很不錯的,如果覺得漢化得不夠好,可以打開這個文件自行修改)。界面部分:

  1. <form id="ff" class="easyui-form" method="post" data-options="novalidate:true">  
  2. <!--form提供了各種方法來操作執行表單字段,比如:ajax提交, load, clear等等。當提交表單的時候可以調用validate方法檢查表單是否有效。  
  3. “data-options”控件的各種屬性,form有以下屬性:  
  4. 屬性名 類型  描述  默認值  
  5. novalidate  boolean     定義是否驗證表單的字段,true:驗證,false:不驗證。  false  
  6. ajax    boolean     定義是否使用ajax提交表單,true:使用,false:不使用。   true  
  7. queryParams     object      當表單被提交到服務器的時候增加的額外參數列表。 {}  
  8. url string      提交表單動作的URL地址    null  
  9. -->  
  10.             <table cellpadding="5">  
  11.                 <tr>  
  12.                     <td>用戶名:</td>  
  13.                     <td><input class="easyui-textbox" type="text" name="username" data-options="required:true" style="width:150px"/></td>  
  14.  <!--  
  15. TextBox(文本框)是一個增強的輸入字段組件, 它允許用戶非常簡單的創建一組表單。它是一個用于構建其他組合控件的基礎組件,如:combo,databox、spinner等  
  16.  required:true表示文本框不能為空,下同。  
  17. -->  
  18.                 </tr>  
  19.                 <tr>  
  20.                     <td>密 碼:</td>  
  21.                     <td><input class="easyui-textbox" type="password" name="passw" data-options="required:true" style="width:150px"/></td>  
  22.                 </tr>  
  23.             </table>  
  24.         </form>  
  25.         <div style="width:216px;padding:5px 0px;height:30px">  
  26.             <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()" style="width:80px;float:left">登陸</a>  
  27. <!--easyui-linkbutton按鈕組件,使用超鏈接按鈕創建,提示:不要將它改為button類別,IE9以下瀏覽器會不正常,submitForm()提交數據,clearForm()清空數據-->  
  28.             <a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()" style="width:80px;float:right">取消</a>  
  29.         </div>  
  30.         </div>  
  31.     </div>  
  登陸界面基本完成,有些簡陋,當然可以自行修改。下面實現提交數據和清空數據,用Javascript:

[javascript] view plaincopy
  1.         function submitForm(){  
  2.             $('#ff').form('submit',{//這是EasyUI的Form自帶功能,就是提交數據  
  3.                 url:'Login.php'//需要把數據提交到的頁面  
  4.                 onSubmit:function(){//驗證數據是否為空,如果為空就返回。  
  5.                     return $(this).form('enableValidation').form('validate');  
  6.                 },  
  7.                 success: function(data){  
  8. //提交成功后的回調函數,data就是返回的數據  
  9.                     if(parseInt(data)==1)  
  10. //我們在這里返回1和0,1表示成功登陸,在后臺實現  
  11.                     {  
  12.                         window.location='main.html';  
  13. //登陸成功后,跳轉到主程序  
  14.                     }  
  15.                     else  
  16.                     {  
  17.                         $.messager.alert('錯誤','用戶名或密碼錯誤!','error');  
  18. /*EasyUI消息提示框,就是alert的改進用法,顯示警告窗口。 
  19. 參數(依次調用): 
  20. title:在頭部面板顯示的標題文本。 
  21. msg:顯示的消息文本。 
  22. icon:顯示的圖標圖像。可用值有:error,question,info,warning。 
  23. fn: 在窗口關閉的時候觸發該回調函數。 */  
  24.                         $('#ff').form('clear');//清空數據,下同。  
  25.                     }  
  26.                 }      
  27.   
  28.                   
  29.             });  
  30.         }  
  31.         function clearForm(){  
  32.             $('#ff').form('clear');  
  33.         }  

  文件另存為“index.html”,即首頁,放在wwwroot下(注意easyui的相關文件也要放在這個目錄下),啟動程序后,就是直接訪問這個頁面了,沒有“$”這個標志。
  登陸界面基本完成,數據需要提交到“Login.php”這個頁面,按一般的做的法,新建一個IWForm,使用模板加載文件,本文用另一種思路,也是本文的關鍵:
用delphi新建一個Unit,命名Login單元,加入IW工程。

直接貼出代碼(參考萬一博客):

[delphi] view plaincopy
  1. {新建Login 單元, 從 TContentBase 繼承實現一個 TLogin 類}  
  2. unit Login;  
  3.   
  4. interface  
  5. uses Classes, IW.Content.Base, System.SysUtils,HTTPApp, IWApplication, IW.HTTP.Request, IW.HTTP.Reply, IWMimeTypes;  
  6.   
  7.   
  8. type  
  9.   TLogin = class(TContentBase)  
  10.   protected  
  11.     function Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication; aParams: TStrings): Boolean; override;  
  12.   public  
  13.     constructor Create; override;  
  14.   end;  
  15.   
  16. implementation  
  17.  uses ServerController,UserSessionUnit;  
  18. { TLogin }  
  19.   
  20. constructor TLogin.Create;  
  21. begin  
  22.   inherited;  
  23.   mFileMustExist := False;  
  24. end;  
  25.   
  26. function TLogin.Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication; aParams: TStrings): Boolean;  
  27. begin  
  28.   aReply.ContentType := MIME_HTML;  
  29.   aReply.WriteString('這里就是返回到客戶端的數據');  
  30.   Result := True;  
  31. end;  
  32.   
  33. end.   
  34.   
  35. {在 IWServerControllerBase.OnConfig  映射login.php}  
  36. uses  
  37.   IWInit, IWGlobal, IW.Content.Handlers, Login;  
  38.   
  39. procedure TIWServerController.IWServerControllerBaseConfig(Sender: TObject);  
  40. begin  
  41.   THandlers.Add('''login.php', TLogin.Create);  
  42. //添加虛擬文件名,映射到服務器  
  43. end;  

  直接列出代碼大家可以不太清楚怎么回事,這里說明一下流程:
  客戶端通過Form提交用戶名和密碼到“Login.php”,“Login.php”是通過服務器添加的一個虛擬文件,映射到從 TContentBase繼承實現的TLogin類,用THttpRequest接收提交的數據,并進行處理,用 THttpReply.writestring寫入返回客戶端數據。這樣登陸過程前臺與后臺代碼均完成。

  第二步:實現主界面
  我們開發的是一個商品信息管理程序,主界面用EasyUI的Layout實現自適應瀏覽器(記得引入相關js和css):
  1. <div data-options="region:'north',border:false" style="height:60px;background:#B3DFDA;padding:0px 10px;text-align:center">  
  2. <h3>商品信息管理系統</h3>  
  3. </div>  
  4. <div data-options="region:'west',split:true,title:'商品分類'" style="width:200px;padding:10px;">  
  5.   
  6. </div>  
  7. <!--<div data-options="region:'east',split:true,collapsed:true,title:'East'" style="width:100px;padding:10px;">east region</div>-->  
  8. <div data-options="region:'south',border:false" style="height:50px;background:#A9FACD;padding:10px;">  
  9. 京ICP證000000號  
  10. </div>  
  11. <div data-options="region:'center',title:'商品簡要信息'">  
  12.   
  13. </div>  

  很好理解,即左西右東,上北下南加上中央的布局,右邊不需要,我把它注釋掉。

  頁面設計思路是這樣的,左邊放一個Tree,用來顯示商品分類,中央放GridData,用來顯示商品信息列表,通過兩個控件實現刪除、添加、修改功能。
  west這個DIV內加入Tree:
  1. <ul id="easyui_tt" class="easyui-tree"   
  2. data-options="  
  3. animate:true,//動畫  
  4. lines:true,//顯示樹線  
  5. url:'Treedata.php',//上面有解釋,需要提交的頁面  
  6. method:'post',//提交方式Post,再強調一下必須用Post  
  7. onClick: function(node){//鼠標單擊事件  
  8. QueryByID(node.id);//通過node.id來查詢數據,講DataGrid時再說  
  9. },  
  10. onContextMenu: function(e, node){//右鍵菜單  
  11. e.preventDefault();//必須用的  
  12. $(this).tree('select', node.target);//選擇的Node  
  13. $('#mm').menu('show', {//EasyUI的菜單,非常簡單  
  14. left: e.pageX,//彈出菜單的位置  
  15. top: e.pageY  
  16. });  
  17. }">  
  18. </ul>  
  Tree的屬性很多,其中一個比較重要的是node,即Tree的節點每個節點都具備以下屬性:
  id:節點ID,對加載遠程數據很重要。
  text:顯示節點文本。
  state:節點狀態,'open' 或 'closed',默認:'open'。
  如果為'closed'的時候,將不自動展開該節點。
  checked:表示該節點是否被選中。
  attributes: 被添加到節點的自定義屬性。
  children: 一個節點數組聲明了若干節點
  Tree的節點是通過url提交請求到服務器接收返回數據加載的,形成
  樹的數據是JSon格式,我們可以分析一下:
[javascript] view plaincopy
  1. [{      
  2.     "id": 1,//對應node的ID,其他也是一一對應的      
  3.     "text""Node 1",      
  4.     "state""closed",      
  5.     "children": [{ //子node     
  6.         "id": 11,      
  7.         "text""Node 11"     
  8.     },{      
  9.         "id": 12,      
  10.         "text""Node 12"     
  11.     }]      
  12. },{      
  13.     "id": 2,      
  14.     "text""Node 2",      
  15.     "state""closed" //不展開節點   
  16. }]}    
  同 上面的“登陸”,我們從TContentBase繼承實現一個 TTreeData 類直接復制模板,修改一個即可,注意加入IW工程,并在ServerController內映射“TreeData.php”。我們現在需要通過 delphi來實現樹,Tree的層越多就越復雜,我發現
不管通過什么語言動態實現Tree,都是非常麻煩的一件事,EasyUI的例子只能實現兩層樹。從數據庫讀取Tree數據,在數據庫設計的時候有一個技 巧,不知道大家是怎樣處理的,我這里說一個我的方法:樹的上下級之間用代碼表示,2位數字代表根,4位數字代表下一級,依此類推,代碼不能用純數字,這樣 不好排序,我在數字前加個字母,這樣通過“select*from Tree order by id”就可以把上下級排列在一起,而不是按代碼大小排序。數據庫就不多講了,不在本文的范圍,大家看一下我的源碼里的數據庫就知道了。建樹代碼如下(本想 用JSon,無奈學不到家,只能用字符串拼接):
[delphi] view plaincopy
  1. function BuildTree:string;  
  2. var  
  3.  i,j,old_ln,new_ln:Integer;  
  4.  id,s,title,ft:string;  
  5. begin  
  6. ft:='{"id":"%s","text":"%s"},';//Json格式  
  7. with UserSession.FDQuery1 do  
  8. begin  
  9.   Open('select*from Tree order by id'); //按id排序可以將父子節點正好羅列在一起  
  10.   s:='[';  
  11.   old_ln:=0;//初始化開始節點ID的長度  
  12.   for i := 0 to RecordCount-1 do  
  13.     begin  
  14.        id:=Fields.Fields[0].AsString;  
  15.        title:=Fields.Fields[1].AsString;  
  16.        new_ln:=id.Length-3;//新節點ID的長度,減去3除去了根節點的長度,方便計算  
  17.        //通過比較與上一節點ID的長度來判斷節點的上下級關系  
  18.        if (new_ln=old_ln) then//與上一節點同等級  
  19.           s:=s+Format(ft,[id,title]);  
  20.        if new_ln>old_ln then //上一節點為父節點  
  21.           begin  
  22.             s:=s.Substring(0,s.Length-2);  
  23.             s:=s+Format(',"state":"closed","children":['+ft,[id,title]);  
  24.           end;  
  25.        if (new_ln<old_ln) then //上一節點為子節點  
  26.           begin  
  27.             s:=s.Substring(0,s.Length-1);  
  28.             for j :=1 to (old_ln-new_ln) div 2 do  
  29.               s:=s+']}';  
  30.             s:=s+Format(','+ft,[id,title]);  
  31.           end;  
  32.       Next;  
  33.       old_ln:=new_ln;//將當前節點ID長度賦予舊節點  
  34.     end;  
  35. end;  
  36.    s:=s.Substring(0,s.Length-1);  
  37.    for i := 1 to new_ln div 2 do //結束時需要判斷是否為子節點,有幾層  
  38.      s:=s+']}';  
  39.    result:=s+']';  
  40. end;  
  以上代碼已經注釋,有什么不明白的地方我們再交流,可以實現N多級樹,只要客戶端支持,有的控件是不支持多級樹的。Tree實現了,我們再實現右鍵菜單,onContextMenu:
[javascript] view plaincopy
  1. onContextMenu: function(e, node){  
  2. e.preventDefault();  
  3. $(this).tree('select', node.target);  
  4. $('#mm').menu('show', {  
  5. left: e.pageX,  
  6. top: e.pageY  
  7. });  
  注意$('#mm')這個就是右鍵菜單的JQuery標識,我們做一個刪除、添加功能,代碼如下:
  1. <div id="mm" class="easyui-menu" style="width:120px;">  
  2. <div onclick="addnode()" data-options="iconCls:'icon-add'">添加</div>  
  3. <div onclick="removeit()" data-options="iconCls:'icon-remove'">刪除</div>  
  4. </div>  

  提示:EasyUI很多情況下只需要引用$('')類似的標識就可以將其他控件加進去。實現addnode()、removeit()以及其他功能:

[javascript] view plaincopy
  1. <span style="white-space:pre">        </span>function appendn(r){//添加節點  
  2.             var t = $('#easyui_tt');  
  3.             var node =t.tree('getSelected');  
  4.             var pii=node.id;  
  5.             $.ajax({    
  6.                 type : "post",    
  7.                 url : "Treedata.php",    
  8.                 data : {Action:'Add',ID:pii,Title:r},    
  9.                 async : false,//這里必須用同步    
  10.                 success : function(data){    
  11.                     pii=data;  
  12.                 }    
  13.             });  
  14.             t.tree('append', {  
  15.                 parent: (node?node.target:null),  
  16.                 data: [{id:pii,text:r}]  
  17.             });  
  18.         }  
  19.         function removeit(){//刪除節點  
  20.             var node = $('#easyui_tt').tree('getSelected');  
  21.             var pii=node.id;  
  22.             $.post('Treedata.php',{Action:'Del',ID:pii});  
  23.             $('#easyui_tt').tree('remove', node.target);  
  24.         }  
  25.         function collapse(){//樹折疊  
  26.             var node = $('#easyui_tt').tree('getSelected');  
  27.             $('#easyui_tt').tree('collapse',node.target);  
  28.         }  
  29.         function expand(){//樹展開  
  30.             var node = $('#easyui_tt').tree('getSelected');  
  31.             $('#easyui_tt').tree('expand',node.target);  
  32.         }  
  33.         function addnode(){//彈出添加節點對話框,用消息框  
  34.             $.messager.prompt('添加''請輸入需要添加的名稱:'function(r){  
  35.                 if (r){  
  36.                 appendn(r);   
  37.                 }  
  38.             });  
  39.         }  

  這段代碼是用JQuery實現向IW提交數據,即把data以JSon格式提交到服務器$.post('Treedata.php',{Action:'Del',ID:pii});提交刪除功能,是$.ajax的簡單實現,順便說一下,萬一的博客提到
[javascript] view plaincopy
  1. function TestPost(){  
  2.     var mydata="TestMYPost測試一下";  
  3.     executeAjaxEvent("&data="+mydata, null"DoCallBack1"falsenullfalse);  
  4.     //中文在IE下亂碼  
  5. }  
  這樣提交數據,用WebApplication.RegisterCallBack('IWCallBack1', DoCallBack1) 注冊回調接收數據,我覺得用JQuery的post實現更簡單,IWForm內用$.post需要這樣:
[javascript] view plaincopy
  1. $.post(GURLBase+"callback?",  
  2.          {callback:"DoCallBack1",data:"測試一下可以嗎-----?"},  
  3.          function(data){processAjaxResponse(data);},"xml");//必須是xml格式  
  4. }//效果是一樣的,也需要注冊回調函數  
  注:GURLBase等于'/$/'(看著非常不爽的美元符號),修改一下萬一的代碼:
[javascript] view plaincopy
  1. function TestPost(){  
  2. var mydata=escape("TestMYPost測試一下");  
  3. executeAjaxEvent("&data="+mydata, null"DoCallBack1"falsenullfalse);//中文在IE下亂碼,需要escape  
  4. }  
這樣也支持中文了。
  服務器如何處理數據,登陸界面已經詳解,基本類似,添加刪除也不再列代碼,大家可以直接看我的源碼,用delphi實現真的很簡易。
  Tree講完,我們接著講DataGrid:
  center這個DIV內加入:
  1. <table class="easyui-datagrid" style="width:100%;height:400px"   
  2. data-options="singleSelect:true,collapsible:true,fitColumns:true,url:'GridData.php',  
  3. method:'post',pageSize:10,pagination:true,onDblClickRow:onDClickRow"   
  4. <!--  
  5. 相同的屬性不再說明,  
  6. singleSelect選擇單行  
  7. collapsible定義是否顯示可折疊按鈕,EasyUI大部分控件繼承自panel,一般可折疊  
  8. fitColumns列寬自適應  
  9. pageSize分頁時每頁顯示的行數  
  10. pagination是否分布  
  11. -->  
  12. toolbar="#dg_tb"//工具欄,EasyUI可以這種方式嵌入其他控件  
  13. id="easyui_tb">  
  14. <thead><!--頭部-->  
  15. <tr>  
  16. <th data-options="field:'codeID',width:80,halign:'center',editor:'text'">商品編號</th>  
  17. <!--field對應數據庫字段  
  18.    halign標題居中  
  19. editor:'text'編輯樣式為文本框  
  20. align:'center'整列居中  
  21. -->  
  22. <th data-options="field:'p_name',width:100,halign:'center',editor:'text'">名稱</th>  
  23. <th data-options="field:'p_type',width:80,halign:'center',align:'center',editor:'text'">型號</th>  
  24. <th data-options="field:'p_tid',width:80,halign:'center',align:'center',editor:'text'">類別</th>  
  25. <th data-options="field:'p_pinpai',halign:'center',width:250,editor:'text'">品牌</th>  
  26. <th data-options="field:'p_price',halign:'center',width:60,align:'center',editor:'text'">價格</th>  
  27. <th data-options="field:'p_discount',halign:'center',width:60,align:'center',editor:'text'">折扣</th>  
  28. </tr>  
  29. </thead>  
  30. </table>  
  31. <div id="dg_tb" style="padding:3px"><!--工具欄-->  
  32. <span>商品編號</span>  
  33. <input id="codeID" class="easyui-numberbox" style="line-height:22px;border:1px solid #ccc">  
  34. <span>商品名稱</span>  
  35. <input id="p_name" class="easyui-textbox" style="line-height:22px;border:1px solid #ccc">  
  36. <a href="#" class="easyui-linkbutton" plain="true" onclick="doSearch()">查詢</a>  
  37. <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true" onclick="appendr();">添加</a>  
  38. <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true" onclick="remover()">刪除</a>  
  39. <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-save',plain:true" onclick="acceptr()">修改</a>  
  40. <a href="javascript:void(0)" class="easyui-linkbutton" data-options="iconCls:'icon-undo',plain:true" onclick="rejectr()">撤消</a>  
  41. </div>  
DataGrid功能強大,也很復雜,本文只講基本應用,大家可以看我上傳的EasyUI幫助文件。從服務器端獲取表格數據同上,數據也是JSon格式的,建一個MyGridData,上面講Tree時留下一下函數未講解QueryByID(node.id),JS如下:
[javascript] view plaincopy
  1. function QueryByID(id){//以節點ID查詢  
  2. var tb=$('#easyui_tb');  
  3. tb.datagrid({queryParams:{Action:'Q_ID',ID:id}});  
  4. /*queryParams是DataGrid提交數據時的參數, 
  5. 也可以直接:tb.datagrid('load',:{Action:'Q_ID',ID:id}}); 
  6. 但是在測試中發現,這樣提交后數據為空時,表仍然顯示有數據, 
  7. 也許是Bug,也許是我不會用。load即是post數據到服務器,同時 
  8. 接收返回數據,GridData全部封閉好了。 
  9. */  
  10. tb.datagrid('load');  
  11. }  

  以ID查詢數據在服務器端這樣實現:

[delphi] view plaincopy
  1. function QueryData(config:string):string;  
  2. var  
  3.  arrjson:JSONArray;  
  4.  ajson:JSONObject;  
  5.  i,j:integer;  
  6. begin  
  7.   arrjson:=JSONArray.Create;  
  8.   ajson:=JSONObject.Create;  
  9.   with UserSession.FDQuery1 do  
  10.    begin  
  11.       Open('select*from product where '+config);  
  12.       for I :=0 to RecordCount-1 do  
  13.        begin  
  14.          for j := 0 to Fields.Count-1 do  
  15.             ajson.Put(Fields.Fields[j].DisplayName,Fields.Fields[j].AsString);  
  16. //形成'{aaa:"BBB",ccc:"DDDD"}'這樣的字符串,不需要拼接字符串了。  
  17.          arrjson.AddJSON(ajson.ToString(4));  
  18. //字面上理解就是JSon數組,即[{},{}];  
  19.          ajson.Clear;  
  20. //清除ajson內的數據,不然ajson會不停put數據,類似js的push用法          
  21.          Next;  
  22.        end;  
  23.   
  24.       
  25.    end;  
  26.   Result:='{"total":'+i.ToString+',"rows":'+arrjson.ToString(4)+'}';  
  27. //ToString(4)表示以4個空格縮進,不這樣使用json數據會被轉義  
  28. //datagrid數據多出的total是分頁時用到的,表示總行數,rows表示當前顯示頁面   
  29. //如果不分頁,可以直接: Result:=arrjson.ToString(4)';   
  30.   arrjson.Free;  
  31.   ajson.Free;  
  32.   
  33. end;  

  我是直接以查詢條件為參數的,以便于擴展,這里用到了yxdJson,在我上傳的控件中有,比較好用,其實就是形成 '{aaa:"BBB",ccc:"DDDD"}'這樣的語句,特別簡潔,不用拼接字符串(拼接字符串是很痛苦的)。Tree的數據我也想用的,但死活不 行,只好放棄。GridData是用服務器實現分頁的,也特簡單,即提交page和rows這個兩個參數到服務器,代碼大家自已下載,delphi實現也 非常簡單,sql查詢時加入limit (page-1)*rows,rows條件即可。注意字符串與整數的變換。實現查詢、刪除、添加、修改功能,客戶端js:
[javascript] view plaincopy
  1. function doSearch(){//查詢功能  
  2. $('#easyui_tb').datagrid('load',{  
  3. Action:'Q_DN',  
  4. id: $('#codeID').val(),  
  5. p_name: $('#p_name').val()  
  6. });}//load參數即可,上面有講解  
  7. var editIndex = undefined;  
  8. var ExecType='';  
  9. function endEditing(){//結束編輯  
  10. if (editIndex == undefined){return true}  
  11. if ($('#easyui_tb').datagrid('validateRow', editIndex)){  
  12. var ed = $('#easyui_tb').datagrid('getEditor', {index:editIndex,field:'codeID'});  
  13. $('#easyui_tb').datagrid('endEdit', editIndex);  
  14. editIndex = undefined;  
  15. return true;  
  16. else {  
  17. return false;  
  18. }  
  19. }  
  20. function onDClickRow(index){//雙擊編輯整行數據  
  21. if (editIndex != index){  
  22. if (endEditing()){  
  23. var  tt=$('#easyui_tb').datagrid('selectRow', index);  
  24. var EditID=tt.datagrid('getSelected')['codeID'];//選擇行的codeID值  
  25. tt.datagrid('beginEdit', index);  
  26. editIndex = index;  
  27. ExecType='update,'+EditID;//提交到服務器update  
  28. else {  
  29. $('#easyui_tb').datagrid('selectRow', editIndex);  
  30. //數據庫必須依靠主鍵為標志來更新。  
  31. }  
  32. }  
  33. }  
  34. function appendr(){//添加  
  35. if (endEditing()){  
  36. $('#easyui_tb').datagrid('appendRow',{p_discount:'1.0'});  
  37. editIndex = $('#easyui_tb').datagrid('getRows').length-1;  
  38. $('#easyui_tb').datagrid('selectRow', editIndex)  
  39. .datagrid('beginEdit', editIndex);  
  40. //添加一行空行   
  41. ExecType='insert into,';//提交到服務器insert  
  42. }  
  43. }  
  44. function remover(){//刪除  
  45. var  tt=$('#easyui_tb').datagrid('getSelected');//找到選擇行  
  46. if (tt==undefined) return;  
  47. //沒有選擇就退出  
  48. var Delindex=$('#easyui_tb').datagrid('getRowIndex',tt);  
  49. //選擇行的行號  
  50. var DelID=tt['codeID'];//主鍵,用于刪除  
  51. $.messager.confirm('刪除','您確認想要刪除記錄嗎?',  
  52. function(r){ if (r){  
  53. $('#easyui_tb').datagrid('deleteRow', Delindex);  
  54. $.post('GridData.php',{Action:'delete',id:DelID});  
  55. //提交delete  
  56. }});    
  57. editIndex = undefined;//這個本程序沒用上,是單擊時用的  
  58. }  
  59. function acceptr(){//修改編輯的數據,添加或編輯后,需要修改數據,提交到服務器  
  60. //不修改只是客戶端更新,服務器端數據庫沒變  
  61. if (endEditing()){  
  62. $('#easyui_tb').datagrid('acceptChanges');  
  63. if (ExecType==''return;  
  64. var selrow=$('#easyui_tb').datagrid('getSelected');  
  65. var row=new Array();  
  66. if(selrow!=undefined)  
  67. row.push(selrow['codeID'],selrow['p_name'],selrow['p_type'],selrow['p_tid'],  
  68.         selrow['p_pinpai'],selrow['p_price'],selrow['p_discount']);  
  69. //push就是將數據壓入數組  
  70. var param=ExecType.split(',');//分割字符串為數組,delphi的用法類似  
  71. if(param[0]=='update')  
  72. {  
  73. $.post('GridData.php',{Action:param[0],id:param[1],Rowdata:row.toString()},function(data){alert(data)});  
  74. //update時要提交動作、codeID和更新后的數據,  
  75. //post的參數function(data){alert(data)就是服務器返回數據。  
  76. }  
  77. if(param[0]=='insert into')  
  78. {  
  79. $.post('GridData.php',{Action:param[0],Rowdata:row.toString()},function(data){alert(data)});  
  80. //insert時要提交動作和插入后的數據  
  81. }  
  82. ExecType='';  
  83. }  
  84. }  
  85. function rejectr(){//取消  
  86. $('#easyui_tb').datagrid('rejectChanges');  
  87. ExecType='';  
  88. editIndex = undefined;  
  89. }  
  90. function getChanges(){  
  91. var rows = $('#easyui_tb').datagrid('getChanges');  
  92. return rows;  
  93. }  
  服務器實現這些功能用下面這個函數:
function Exec_SQL(act,id,row:string):string;
  源碼自己去看,很簡單,就是操作數據庫。本文基本完成,最后講一下這種 方式未完成的功能:直接使用http://xxx.xxx.xxx/main.html可以不用登陸就能進入主界面,顯然不是我們所期望的,可以在主界面 加入驗證登陸的功能,也很簡單,可以在頁面加載之前$.post提交驗證信息到login.php,里面代碼已經寫了,只是客戶端沒有添加。還有第三大 點。
  三、動態加載
  動態加載簡單說就是,客戶端還是單獨做出來,不用放在wwwroot下面,引用js和css時需要在路徑前面多加一個“/”即可。仍然從TContentBase 繼承實現一個類,在函數中這樣實現 :
[delphi] view plaincopy
  1. function TMyIndex.Execute(aRequest: THttpRequest; aReply: THttpReply; const aPathname: string; aSession: TIWApplication; aParams: TStrings): Boolean;  
  2. var  
  3.  ss:Tstrings;  
  4. begin  
  5.   aReply.ContentType := MIME_HTML;  
  6.   ss:=TstringList.create;  
  7.   ss.loadformfile('做好靜態頁面');  
  8.   aReply.WriteString(ss.text);  
  9.   ss.free;  
  10.   Result := True;  
  11. end;  
  這樣顯而易見是比較安全的,可以在加載主界面前先驗證有無登陸,還可以在加載頁面中加一些類似模板替換標識,動態加載時,將這些標識替換成本頁面需要展示的內容,實現header、body、footer共用。

  本文所需要工具:delphiXE7+Intraweb 14.0.38

 

源碼 見   http://bbs.2ccc.com/topic.asp?topicid=479014

作者:zhang_y_b 錄入:142857 來源:轉載
共有評論 2相關評論
發表我的評論
  • 大名:
  • 內容:
本類推薦
本類固頂
  • 盒子文章(www.srtxuk.icu) © 2019 版權所有 All Rights Reserved.
  • 滬ICP備05001939號
  • 快乐10分助手官网