extJS模板

EXT是一款强大的AJAX框架,其UI设计非常华丽,所以在对UI要求高的项目中可以使用! 
        前面一段时间发了一篇封装的EXT CRUD面板,地址为http://www.phpchina.com/bbs/thread-59552-1-1.html 
只是单纯的贴出了代码,对于其中的运行原理并未提及到,这篇文章将分享该CRUD面板实现原理,好了,不废话,正式开始。 
       下面的内容是毕业论文中的一部分,所以大家看看就是 

  EXT做为与用户交互的前端,其功能可以概括为:生成用户界面,与用户实现交互,并与程序(PHP,.NET等)后台通信来完成与用户的交互。下面就这几个功能的实现原理做介绍。 
1.1生成用户界面 

EXT别广泛接受认可的原因之一便是他拥有良好的用户外观。 

一个系统中最主要的功能便是实现CRUD(新增,读取,更新,删除),同时还有查询。为了将这些功能集中在一起,特意封装了一个EXT的CRUD面板,将这些常用的功能封装成一个类,以便创建易用性良好的界面。该CRUD类的程序代码见前面的文章。 
CRUD面板是从EXT的panel继承来的 
Javascript代码  收藏代码
  1. /** 
  2. * 定义命名空间 
  3. */  
  4. Ext.namespace("Mis.Ext");  
  5. /* 
  6. *CRUD面板基类 
  7. */  
  8. //继承EXT的Panel,创建CRUD面板  
  9. Mis.Ext.CrudPanel=Ext.extend(Ext.Panel,{……});  
  10. //限于篇幅就不列出全部代码  
  11. //EXT里的继承用的是Ext.extend(组件名,{实现代码});  
  12. //要使用这个CRUD面板,需要继承实现它,我们举一个例子  
  13. //继承CrudPanel,创建污水厂管理面板  
  14. AddPlantPanel=Ext.extend(Mis.Ext.CrudPanel,{  
  15.     id:"AddPlantPanel",//id号是表示一个面板的唯一标志  
  16.     title:"污水厂管理",//面板的名称,见上图  
  17.     baseUrl:"Plant.aspx",//数据源地址  
  18.     //根据实际需要,重载编辑方法  
  19.     edit:function(){  
  20.         CommentPanel.superclass.edit.call(this);//调用基类方法  
  21.         var record=this.grid.getSelectionModel().getSelected();  
  22.         if(record){  
  23.             var id=record.get("plantID");  
  24.             this.fp.form.setValues({ID:id});   
  25.         }  
  26.     },  
  27.     save:function(){//保存  
  28.         var id=this.fp.form.findField("ID").getValue();  
  29.         this.fp.form.submit({  
  30.             waitMsg:'正在保存。。。',  
  31.             url:this.baseUrl+"?cmd="+(id?"Update":"Save"),  
  32.             method:'POST',  
  33.             success:function(form_instance_create, action) {  
  34.                 Ext.MessageBox.alert('友情提示', action.result.info);  
  35.             },  
  36.             failure:function(form_instance_create1, action1){  
  37.                 Ext.MessageBox.alert('友情提示', action1.result.info);  
  38.             },  
  39.             scope:this  
  40.         });  
  41.     },  
  42.     removeData:function(){//删除  
  43.         this.remove('plantID');  
  44.     } ,  
  45.     createForm:function(){//创建新建和修改的表单  
  46.         var formPanel=new Ext.form.FormPanel({  
  47.             frame:true,  
  48.             labelWidth:60,  
  49.             labelAlign:'right',  
  50.             items:[{  
  51.                 xtype:'fieldset',  
  52.                 title:'基本信息',  
  53.                 autoHeight:true,  
  54.                 defaults:{xtype:"textfield",width:300},  
  55.                 items:[  
  56.                 {xtype:"hidden",name:"ID"},  
  57.                 {fieldLabel:'编号',name:'plantID'},  
  58.                 {fieldLabel:'名称',name:'plantName'}]  
  59.             }]  
  60.         });  
  61.         return formPanel;  
  62.     },  
  63.     //创建放置表单的窗口,见上图新增和修改的效果  
  64.     createWin:function(){  
  65.         return this.initWin(438,180,"污水厂管理");  
  66.         //创建新增、添加面板  
  67.     },  
  68.     //指定JSON数据的mapping  
  69.     storeMapping:["plantID","plantName"],  
  70.       
  71.     initComponent : function(){//初始化界面  
  72.         var sm = new Ext.grid.CheckboxSelectionModel();  
  73.         this.cm=new Ext.grid.ColumnModel([new Ext.grid.RowNumberer(),//获得行号  
  74.             sm,  
  75.             //定义GRID的表头信息  
  76.             {header: "污水厂编号", sortable:true,width: 100, dataIndex:"plantID"},  
  77.             {header: "污水厂名称", sortable:true,width: 200, dataIndex:"plantName"}  
  78.         ]);  
  79.         AddPlantPanel.superclass.initComponent.call(this);  
  80.     }  
  81. });  

这样就完成了一个能应用到实际中的CRUD面板,效果见下图 
1.2与用户实现交互和与程序后台实现通信 

EXT的组件在执行时是从initComponent开始的 
我们来看看AddPlantPanel这个具体的CRUD面板的执行过程 
Javascript代码  收藏代码
  1. initComponent : function(){  
  2.     var sm = new Ext.grid.CheckboxSelectionModel();  
  3.     this.cm=new Ext.grid.ColumnModel([new Ext.grid.RowNumberer(),//获得行号  
  4.         sm,  
  5.         //定义GRID的表头信息  
  6.         {header: "污水厂编号", sortable:true,width: 100, dataIndex:"plantID"},  
  7.         {header: "污水厂名称", sortable:true,width: 200, dataIndex:"plantName"}  
  8.     ]);  
  9.     AddPlantPanel.superclass.initComponent.call(this);  
  10. }  


    首先是定义Grid表格的相关信息,接着是调用基类的initComponent方法,注意,EXT里面调用基类的方法是用superclass.方法名.call(this); 
    接着看基类方法里的initComponent 
initComponent : function(){ 
       //首先是定义数据源 
this.store=new Ext.data.JsonStore({ 
id:"Id", 
url: this.baseUrl+'?cmd=List',//默认的数据源地址,继承时需要提供 
root: "rows", 
totalProperty:"totalCount", 
remoteSort:true, 
fields:this.storeMapping}); 
this.cm.defaultSortable=true;//开启排序 
this.sm= new Ext.grid.CheckboxSelectionModel(); //选择框 
Mis.Ext.CrudPanel.superclass.initComponent.call(this);//初始化panel 
var viewConfig=Ext.apply({forceFit:true},this.gridViewConfig);  //添加配置信息 
        //Grid表格 
this.grid=new Ext.grid.GridPanel({ 
store: this.store, 
cm: this.cm, 
sm:this.sm, 
trackMouseOver:false, 
loadMask: true, 
viewConfig:viewConfig, 
tbar: [……],//顶部工具栏 
bbar: new Ext.PagingToolbar({ 
pageSize: 10, 
store: this.store, 
displayInfo: true, 
displayMsg: '显示第 {0} - {1} 条记录,共 {2}条记录', 
emptyMsg: "没有记录" 
})//底部工具栏,放置分页信息            
}); 
//双击时执行修改 
this.grid.on("celldblclick",this.edit,this); 
this.add(this.grid); //将Grid表格添加到panel内,很重要 
this.store.load({params:{start:0,limit:10}});//Grid表格生成后,接着是加载数据,这里是与服务器端通信的关键 
上面代码与服务器通讯的关键在于url: this.baseUrl+'?cmd=List',和this.store.load({params:{start:0,limit:10}}); 
    url:指定了数据源的地址,在页面初始化时EXT调用this.store.load方法从this.baseUrl+'?cmd=List获取数据,参数为start=0&limit=10,即从 Plant.aspx?cmd=List& start=0&limit=10获取数据 
当请求到达服务器端Plant.aspx?cmd=List& start=0&limit=10时(毕业设计用的.NET,其实后台都很简单),下面的代码执行 
if(Request.Params["cmd"].ToString()=="List"){ 
int start =Convert.ToInt32(Request.Params["start"].ToString()); 
int limit = Convert.ToInt32(Request.Params["limit"].ToString()); 
string json = pnt.GetJsonAll(start, limit, ""); 
Response.Write(json); 

//ps这是c#,php的以前发过,自己去找 

上面的代码生成了一段JSON数据 
{'totalCount':'5','rows': [{"plantID":"8","plantName":"ss"},{"plantID":"7","plantName":"7号污水处理厂修改 banben"},{"plantID":"23","plantName":"222"}, {"plantID":"22","plantName":"22"},{"plantID":"15","plantName":"15号污水处理 厂"}]} 

EXT读取上面的JSON,兵将数据显示在表格中,这是与服务器的第一次通信 
效果如下 
 
主要流程 
 

页面呈现给用户后接着就是与用户执行交互。 

在Mis.Ext.CrudPane基类的初始化函数initComponent中有下面这段代码 
tbar: [{ 
id:'addButton', 
text: '新增', 
iconCls:'addIconCss', 
tooltip:'添加新纪录', 
handler: this.create, 
scope:this 
},'-',//'-'给工具栏按钮之间添加'|' 


id:'editButton', 
text:'编辑', 
iconCls:'editIconCss', 
tooltip:'修改记录', 
handler: this.edit, 
scope:this 
},'-', 


text:'删除', 
iconCls:'deleteIconCss', 
tooltip:'删除所选中的信息', 
handler: this.removeData, 
scope:this 

},'-', 


text:'刷新', 
iconCls:'refreshIcon', 

tooltip:'刷新纪录', 

handler: this.refresh, 

scope:this 

},'->',//'->'代表让工具栏按钮到右边去 
            'Search: ',this.name, 

{text: '查询',pressed: true, 


iconCls:'selectIconCss', 


handler: this.search, 

scope:this 

},' 


], 


上面定义了面板顶部工具栏的按钮(效果见上图中的按钮),每个按钮都有一个handler,其参数是该类里的一个成员方法。当点击一个按钮时,便触发这个按钮handler对应的方法,比如点击新增,那么便会触发this.create方法,下面我们跟踪其执行路径。 
见下面…… 

 


 


 

首先是执行create方法,create方法如下 


//创建(新增/修改)窗口 

create:function() 


this.showWin();//显示(新增/修改)窗口 

this.reset();//清空表单里的数据 



Create方法中有两个函数,依次执行 

//显示(新增/修改)窗口 

showWin:function() 


//createForm()需要在继承时提供,该方法作用是创建表单 

if(!this.win){ 

if(!this.fp){ 

this.fp=this.createForm(); 



this.win=this.createWin(); 

this.win.on("close",function(){this.win=null;this.fp=null;this.store.reload();},this);//添加事件,当窗口关闭时表格数据重新加载 



//窗口关闭时,数据重新加载 

this.win.show(); 

}, 


Showwin调用createWin()方法创建一个窗口,并将表单放在里面。而create里的第二个方法则是将表单的内容重置。这样就显示出了一个新增的画面 

 


   下面我们来看createWin()方法 
//创建放置表单的窗口,见上图新增和修改的效果 

createWin:function() 




return this.initWin(438,180,"污水厂管理"); 

//创建新增、添加面板 
}, 

该方法调用了initWin方法来创建窗口,为了更清晰的理解,我们再看看initWin方法 
initWin:function(width,height,title) 




var win=new Ext.Window({ 

width:width, 

height:height, 

buttonAlign:"center", 

title:title, 

modal:true, 

shadow:true, 

closeAction:"hide", 

items:[this.fp], 

buttons:[{text:"保存", 


handler:this.save, 


scope:this}, 


{text:"清空", 


handler:this.reset, 


scope:this}, 


{text:"关闭", 


handler:this.closeWin, 


scope:this} 







}); 

return win; 
}, 

注意 
{text:"保存", 
handler:this.save, 
scope:this}, 

当用户填完数据点击保存时,触发save方法,于是EXT调用save方法 

 


//保存 

save:function() 





var id=this.fp.form.findField("ID").getValue(); 



this.fp.form.submit({ 

waitMsg:'正在保存。。。', 


url:this.baseUrl+"?cmd="+(id?"Update":"Save"), 


method:'POST', 


success:function(form_instance_create, action) { 



Ext.MessageBox.alert('友情提示', action.result.info); 

}, 

failure:function(form_instance_create1, action1){ 


Ext.MessageBox.alert('友情提示', action1.result.info); 


}, 


scope:this 

}); 

}, 

效果 

该方法实现了与ASP.NET后台通讯,将会把表单内的数据用POST方法传到baseUrl?cmd=Save中,因为上面的baseUrl是Plant.aspx,所以最终将数据传送到Plant.aspx?cmd=Save 
[size=+0]EXT将数据传到了.NET后台,接着就是.NET后台处理EXT传来的数据,下面我们看看Plant.aspx怎么处理 
Mis.BLL.Plant pnt = new Mis.BLL.Plant(); 

if (Request.Params["cmd"].ToString() == "Save") 



string id = Request.Params["plantID"].ToString(); 

string name = Request.Params["plantName"].ToString(); 

Mis.Model.Plant pntm = new Mis.Model.Plant(); 

pntm.plantID = id; 

pntm.plantName = name; 

try 



pnt.Add(pntm); 

Response.Write("{success:true,info:'新增成功'}"); 

}catch (Exception adde){ 
Response.Write("{failure:true,info:'新增失败,错误原因为:" + this.addlashes((adde.Message.ToString())) + "'}"); 
}} 

上面的方法实现了将信息保存到数据库,如果成功则返回"{success:true,info:'新增成功'}",这是一个JSON字符串。EXT获取返回的数据,成功就调用save中的: 
success:function(form_instance_create, action) { 
Ext.MessageBox.alert('友情提示', action.result.info); 
}, 

效果 

 
  • 大小: 19.7 KB
  • 大小: 42.8 KB
  • 大小: 22.6 KB
  • 大小: 23.5 KB
  • 大小: 30.7 KB
  • 大小: 30.7 KB
  • 大小: 23.5 KB
  • 大小: 22.6 KB
posted on 2011-12-15 20:50  cy凌云  阅读(2704)  评论(1)    收藏  举报