Ext JS一个完整的EXT应用.docx
- 文档编号:5970917
- 上传时间:2023-01-02
- 格式:DOCX
- 页数:30
- 大小:162.66KB
Ext JS一个完整的EXT应用.docx
《Ext JS一个完整的EXT应用.docx》由会员分享,可在线阅读,更多相关《Ext JS一个完整的EXT应用.docx(30页珍藏版)》请在冰豆网上搜索。
ExtJS一个完整的EXT应用
在本文中,我们将综合运用前面所学的知识,开发一个简单的学生信息管理系统(如图12-1所示)。
该系统的主要功能包括:
显示学生信息、添加学生信息、修改学生信息,以及删除学生信息。
这些功能的实现非常简单,我们在这里将演示如何在EXT中实现这些常用功能。
图12-1 学生信息管理系统界面
第1页:
确定整体布局
在我们动手实现这些功能操作之前,首先应该确定页面的整体布局。
在这里,我们用BorderLayout把页面分隔成4个部分:
最上方显示系统的名称,最下方显示版权信息,中间部分左侧显示学生信息列表,中间部分右侧中的表单用来添加或修改学生信息。
实现上述布局效果的代码如代码清单12-1所示。
代码清单12-1 实现学生信息管理系统的布局
Ext.onReady(function(){
//layoutstart
varviewport=newExt.Viewport({
layout:
'border',
items:
[{
region:
'north',
html:
'head'
},{
region:
'center',
html:
'grid'
},{
region:
'east',
html:
'form'
},{
region:
'south',
html:
'foot'
}]
});
//layoutend
});
我们使用Ext.Viewport为整个页面进行了布局设置,其中每个部分都直接用HTML参数做了标记,现在我们就可以看到这个布局的显示效果如图12-2所示。
图12-2 学生信息管理系统布局效果图
如图12-2所示,现在我们看到的只是一个空白的框架,每一部分的具体内容都需要我们进一步去实现。
无论该学生信息管理系统的功能多么复杂,都不会超出目前框架中的布局设计。
接下来,让我们逐一实现各个部分的功能。
第2页:
使用HTML和CSS设置静态信息
用于显示标题和版权信息的文字都是静态的,我们可以直接调用HTML中设置好的内容。
在Ext.Panel中添加静态信息的方式有如下2种。
qHTML参数:
它让我们可以直接在JavaScript脚本中写上静态信息的内容。
qcontentEl参数:
它引用页面中某一个div的id,在显示Panel时将这个div中的内容显示在对应的布局域中。
相对而言,HTML参数更适合简单的内容。
如果需要引入复杂格式的静态信息,还是应该使用contentEl参数。
在这个示例中,我们就选择了contentEl参数为头部和底部制定静态信息部分的内容,实现方法如代码清单12-2所示。
代码清单12-2 在布局中设置静态内容
varviewport=newExt.Viewport({
layout:
'border',
items:
[{
region:
'north',
contentEl:
'head'
},{
region:
'center',
html:
'grid'
},{
region:
'east',
html:
'form'
},{
region:
'south',
contentEl:
'foot'
}]
});
在上面的代码中,显示在上方的north部分引用的contentEl是'head',它在页面中的内容如下所示。
学生信息管理
显示在下方的south部分引用的contentEl是'foot',它在页面中的内容如下所示。
right;">-©2008 href=""target="_blank">
因为这两部分的标签内容都会在EXT进行页面布局时重新提取和设置,所以我们在开始时不用考虑把这两个div写到页面的什么位置,只要把它们写到页面里,EXT就会自动进行布局,把它们放到预设的位置。
设置过contentEl后,整个页面就变成了图12-3的样子。
我们这里演示的效果比较简单,结合使用了HTML标签和CSS,为标题设置字体(加粗)和字号(变大),版权信息则是右对齐并设置了超链接。
在实际项目中,可以把美工设计出来的页面标签直接复制到对应的div下,刷新页面后就会显示在对应的位置。
图12-3 上下部分加入静态信息的效果
第3页:
对学生信息进行数据建模
接下来我们要实现对学生信息进行实际操作的功能。
我们用Java编写后台脚本,用Hsqldb数据库作为保存数据的介质。
首先要在数据库中创建学生信息数据表,如代码清单12-3所示。
代码清单12-3 创建学生信息表
createtablestudent(
idbigint,--主键
codevarchar(50),--学号
namevarchar(50),--姓名
sexinteger,--性别
ageinteger,--年龄
politicalvarchar(50),--政治面貌
originvarchar(50),--籍贯
professionalvarchar(50)--所属系
);
altertablestudent
addconstraintpk_studentprimarykey(id);
altertablestudent
altercolumnidbigintgeneratedbydefaultasidentity(startwith1,incrementby1);
这张student表中包含8个字段,分别对应学生的各种详细信息。
最后两行不是标准的ANSISQL语句,这是Hsqldb中的特有功能,表示把id字段设置成student表的唯一主键,并由数据库服务器控制自动增长。
我们在示例中将它作为嵌入式内存数据库,只要把hsqldb-1.8.0_7.jar放到WEB-INF/lib目录下就可以使用了,不必再去安装和配置外部服务器。
Hsqldb数据库会在JDBC第一次连接时启动,从WEB-INF/classes目录下的test.scripts和test.properties两个文件中加载初始数据,其后的所有操作都会在内存中进行,唯一的缺陷是以这种方式运行的数据都保存在内存里。
一旦服务器关闭就会导致数据丢失,下次重新启动数据库时将无法得知上次执行过何种操作,我们看到的数据依然是从test.scripts和test.properties中读取的初始化数据。
有关Hsqldb数据库的详细信息可以去它的官方网站www.hsqldb.org查看。
在下面的讨论中,我们将尽量使用标准的ANSISQL语句,保证可以在不同的数据库上正常运行。
对于不得不使用Hsqldb数据库的特定功能的SQL语句,我们会对它们单独进行讨论。
对应已经建立好的数据表结构,我们编写了一个与数据库表结构对应的JavaBean——Stud-ent.java,这个JavaBean中的字段与数据库表中的字段是一一对应的,如代码清单12-4所示。
代码清单12-4 学生信息领域模型
packagecom.family168.student;
publicclassStudent{
privatelongid;
privateStringcode;
privateStringname;
privateintsex;
privateintage;
privateStringpolitical;
privateStringorigin;
privateStringprofessional;
publiclonggetId(){
returnid;
}
publicvoidsetId(longid){
this.id=id;
}
//getterandsetter
}
这是一个简单的JavaBean,它的每个属性对应了student表中的一个字段,我们将数据库中的字段映射为Java对象,在后面的操作里就可以为它们添加特定的逻辑,封装功能,简化操作。
直接操作Student.java的类叫做StudentDao.java,DAO是DataAccessObject的简写,它主要负责Student.java和数据库之间的数据转换。
比如,pagedQuery()会把从数据库中读取的数据放入Student.java对象中,并按照特定的形式返回。
Insert()和update()方法则是将Student.java中的数据保存到数据库中。
Remove()方法执行的是删除操作,它会根据指定的id从数据库中删除对应的对象。
这些对数据库的操作实际上都是大同小异的,每次先打开与数据库的连接,然后执行查询或更新操作,最后关闭连接并释放资源。
我们将获得数据库连接的部分代码封装在一个叫做DbUtils.java的工具类中,如代码清单12-5所示。
代码清单12-5 数据库工具类
packagecom.family168.student;
importjava.sql.*;
publicclassDbUtils{
static{
try{
Class.forName("org.hsqldb.jdbcDriver");
}catch(Exceptionex){
System.err.println(ex);
}
}
staticConnectiongetConn()throwsException{
returnDriverManager.getConnection("jdbc:
hsqldb:
res:
/test","sa","");
}
staticvoidclose(ResultSetrs,Statementstate,Connectionconn){
if(rs!
=null){
try{
rs.close();
}catch(SQLExceptionex){
ex.printStackTrace();
}
rs=null;
}
if(state!
=null){
try{
state.close();
}catch(SQLExceptionex){
ex.printStackTrace();
}
state=null;
}
if(conn!
=null){
try{
conn.close();
}catch(Exceptionex){
ex.printStackTrace();
}
conn=null;
}
}
}
这是一个工具类,不需要使用new关键字实例化就可以直接调用其中的方法,static{}静态初始化时加载Hsqldb的JDBC驱动,其后每次执行getConn()方法就可以得到一个与数据库的连接。
Close()方法提供了一种关闭数据库连接并释放资源的简便方法,使用它可以一次性关闭ResultSet、Statement和Connection3个对象,方法内自动检测对象是否为null,可以放心使用。
在StudentDao.java中统一通过DbUtils.java来获得数据库连接,以此实现对数据库的操作,比如remove()方法中就是先通过DbUtils的getConn()方法获得数据库的连接再进行删除操作的,如下面的代码所示。
publicvoidremove(longid)throwsException{
Stringsql="deletefromstudentwhereid=?
";
Connectionconn=DbUtils.getConn();
PreparedStatementstate=conn.prepareStatement(sql);
state.setLong(1,id);
state.executeUpdate();
DbUtils.close(null,state,conn);
}
先用DbUtils.getConn()获得数据库链接,然后准备SQL语句对应的Statement。
设置指定的id后,调用Statement和executeUpdate()执行删除操作,最后不要忘记用DbUtils.close()关闭与数据库的连接释放资源。
另外两种更新数据库的方法与remove()相似,insert()和update()分别使用的是SQL中的insert和update语句,再将作为参数的Student.java对象设置到Statement中执行更新,实际代码请参考StudentDao.java中的内容,这里就不再赘述了。
pagedQuery()中的查询功能比较复杂,需要详细讨论一下,先看一下其中的代码部分,如代码清单12-6所示。
代码清单12-6 pagedQuery()
publicPagepagedQuery(intstart,intlimit,Stringsort,Stringdir)throws
Exception{
Stringsql="selectlimit"+start+""+limit+"*fromstudent";
if(sort!
=null&&!
sort.equals("")&&dir!
=null&&!
dir.equals("")){
sql+="orderby"+sort+""+dir;
}
Connectionconn=DbUtils.getConn();
Statementstate=conn.createStatement();
ResultSetrs=state.executeQuery(sql);
Listresult=newArrayList();
while(rs.next()){
Studentstudent=newStudent();
student.setId(rs.getLong("id"));
student.setCode(rs.getString("code"));
student.setName(rs.getString("name"));
student.setSex(rs.getInt("sex"));
student.setAge(rs.getInt("age"));
student.setPolitical(rs.getString("political"));
student.setOrigin(rs.getString("origin"));
student.setProfessional(rs.getString("professional"));
result.add(student);
}
rs=state.executeQuery("selectcount(*)fromstudent");
inttotalCount=0;
if(rs.next()){
totalCount=rs.getInt
(1);
}
DbUtils.close(rs,state,conn);
Pagepage=newPage(totalCount,result);
returnpage;
}
先看pagedQuery()方法的4个参数,分别是start、limit、sort和dir。
start和limit用来进行分页查询,start表示从第几条数据进行查询,limit表示最多返回几条查询数据。
sort和dir用来对查询的结果进行排序,sort表示对哪个字段进行排序,dir表示排序时使用升序还是降序。
为了实现分页和排序功能,pagedQuery()方法中首先要根据传递过来的参数生成对应功能的SQL语句。
Stringsql="selectlimit"+start+""+limit+"*fromstudent";
上面是从student表中进行查询,并依据start和limit的内容进行分页。
这里的"selectlimit"+start+""+limit的不是标准的ANSISQL语句,而是Hsqldb专门为分页查询提供的功能。
很不幸的是,标准ANSISQL中没有提供分页查询的功能,基本上每个主流数据库都提供了自己的分页查询方式,这些方式又完全不相同。
如果你想把这个示例转换到其他数据库上,必须将这里的分页查询部分修改为对应数据库的SQL语句。
if(sort!
=null&&!
sort.equals("")&&dir!
=null&&!
dir.equals("")){
sql+="orderby"+sort+""+dir;
}
生成排序功能的SQL语句比较简单,只需要判断sort和dir是否为空。
如果不为空,就可以直接附加到原来的SQL的后面,对获得的查询结果实现排序。
得到了需要的SQL语句之后,我们立刻进行查询,通过Statement和ResultSet,把每一条返回的记录都转换成Student.java对象,放入到ArrayList中。
接下来我们还需要获取数据库中的总记录数,对应的SQL语句为selectcount(*)fromstudent,这是一条标准的ANSISQL语句,不用做任何修改就可以在所有的主流数据库上运行。
使用这条SQL语句,我们获得了数据库中保存的学生信息的总数。
现在我们可以关闭数据库连接,把学生信息总数totalCount和本页显示的学生信息列表result放入Page.java对象中并返回。
至此,我们完成了数据建模部分代码的编写,对应的源代码放在WEB-INF/src目录下,编译后的代码放在WEB-INF/classes目录下。
对应的com.family168.student包下的内容供对应的JSP或其他JAVA类调用,通过这些类,我们可以访问数据库获得需要的查询结果,也可以通过这些类对数据库中的数据进行更新。
第4页:
在页面中显示学生信息列表
后台的数据库和Java代码都已经准备妥当,现在来编写显示学生信息列表的Grid部分的代码,如代码清单12-7所示。
代码清单12-7 前台Prid部分的实现代码
varsexRenderer=function(value){
if(value==1){
return'男';
}elseif(value==2){
return'女';
}
};
varStudentRecord=Ext.data.Record.create([
{name:
'id',type:
'int'},
{name:
'code',type:
'string'},
{name:
'name',type:
'string'},
{name:
'sex',type:
'int'},
{name:
'age',type:
'int'},
{name:
'political',type:
'string'},
{name:
'origin',type:
'string'},
{name:
'professional',type:
'string'}
]);
varstore=newExt.data.Store({
proxy:
newExt.data.HttpProxy({url:
'./jsp/list.jsp'}),
reader:
newExt.data.JsonReader({
totalProperty:
'totalCount',
root:
'result'
},StudentRecord),
remoteSort:
true
});
store.load({params:
{start:
0,limit:
15}});
varcolumns=newExt.grid.ColumnModel([
{header:
'学号',dataIndex:
'code'},
{header:
'姓名',dataIndex:
'name'},
{header:
'性别',dataIndex:
'sex',renderer:
sexRenderer},
{header:
'年龄',dataIndex:
'age'},
{header:
'政治面貌',dataIndex:
'political'},
{header:
'籍贯',dataIndex:
'origin'},
{header:
'所属系',dataIndex:
'professional'}
]);
columns.defaultSortable=true;
//gridstart
vargrid=newExt.grid.GridPanel({
title:
'学生信息列表',
region:
'center',
loadMask:
true,
store:
store,
cm:
columns,
sm:
newExt.grid.RowSelectionModel({singleSelect:
true}),
viewConfig:
{
forceFit:
true
},
bbar:
newExt.PagingToolbar({
pageSize:
15,
store:
store,
displayInfo:
true
})
});
//gridend
sexRenderer是一个工具函数,它用来在Grid中显示学生的性别。
数据库中sex字段的类型为int,我们用1代表“男”,2代表“女”,sexRenderer中使用if语句判断当前行的sex值。
在1的情况下显示红色粗体的“男”,在2的情况下显示绿色粗体的“女”。
之后sexRenderer会作为ColumnModel的一部分设置到Grid中,负责显示“性别”这一列的内容。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Ext JS一个完整的EXT应用 JS 一个 完整 应用