這是一個ExtJS實作的樹展示,背景使用的EJS構架,是以向大家推薦,内容轉自willamRaym的blog。
最近在學習ExtJS,發現其伺服器端是php,這一點對我們搞java的有點不厚道啊。昨天學習了ExtJS的樹,并做了一棵異步更新的樹出來,背景的業務邏輯及持久層使用JPA+Spring2.5實作,發下面把步驟貼出來與大家分享。
首先準備樹的域模型,下面是一地區的域模型對象, Region.java 的代碼如下:
@Entity
public class Region
{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@Field(name = " 名稱 " ,validator = @Validator(name = " string " ,value = " min:2;max:50 " ,required = true ))
@Column(length = 100 )
private String name;
@Field(name = " 編碼 " ,validator = @Validator(name = " string " ,value = " min:2;max:16 " ,required = true ))
@Column(length = 100 )
private String code;
@POLoad(name = " parentId " )
@ManyToOne
private Region parent;
@OneToMany(mappedBy = " parent " ,fetch = javax.persistence.FetchType.EAGER)
private List < Region > children = new java.util.ArrayList < Region > ();
public Long getId()
{
return id;
}
public void setId(Long id)
{
this .id = id;
}
Region域模型有parent,也有children,這個完全是一個樹的結構,如果把樹根砍了話就變成森林了,呵呵這一點跟現實不一樣。其它都是setter及getter方法,這裡就不多說了。
然後我們就要做針對這個地區資訊的添删除改查了。呵呵,添删改查我最拿手了,特别是基于EJS(EasyJWeb+JPA+Spring2)構架的添删改查,一個指令搞定了。這裡就不多說了,大家可以直接看我前段時間做的視訊示範(http://www.easyjf.com/blog/html/20080102/1015814.html)。當然這個示例由于是分級别的,是以生成的添删改查還要改一改,才支援上下級管理功能。
下面進入我們重點部分,如何在頁面中得到一棵表示地區的樹。
首先準備一個tree.html,内容如下:
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" />
< title > ExtJS-樹示例 </ title >
< link rel ="stylesheet" type ="text/css" href ="/plugins/extjs/ext-2.0/resources/css/ext-all.css" />
< script type ="text/javascript" src ="plugins/extjs/ext-2.0/adapter/ext/ext-base.js" ></ script >
< script type ="text/javascript" src ="plugins/extjs/ext-2.0/ext-all.js" ></ script >
< script type ="text/javascript" src ="tree.js" ></ script >
</ head >
< body >
< div align ="center" >
< p > ExtJS-樹的示例 </ p >
</ div >
< div id ="tree-div" ></ div >
</ body >
</ html >
注意幾個<script>标簽,他們是用來引入ext的js以及本示例中用到的樹。tree.js的代碼如下:
Ext.BLANK_IMAGE_URL = 'plugins / extjs / ext - 2.0 / resources / images / default / s.gif';
Ext.onReady( function ()
{
var tree = new Ext.tree.TreePanel(
{
el:"tree-div",
autoScroll:true,
animate:true,
width:'100px',
height:'300px',
enableDD:true,
containerScroll: true,
loader: new Ext.tree.TreeLoader(
{
dataUrl:'region.ejf?cmd=getRegion'
})
});
tree.on("click",function(node,event)
{alert(node.id);});
tree.on('beforeload',function(node)
{
tree.loader.dataUrl = 'region.ejf?cmd=getRegion&id='+(node.id!='root'?node.id:"");
});
var root = new Ext.tree.AsyncTreeNode(
{
text: '地區資訊',
draggable:false,
id:'root'
});
tree.setRootNode(root);
tree.render();
root.expand();
} );
其實tree.js的代碼跟ExtJS官方示例中的差别不大,這裡就不對這個代碼作詳細的解釋,如果你感興趣的話,可以在後面留言或給我發電子郵件。如果需要的人多的話,我看能否補充。這裡把重點的代碼強調一下。
loader: new Ext.tree.TreeLoader(
{
dataUrl:'region.ejf?cmd=getRegion'
} )
這個表示通過region.ejf?cmd=getRegion來加載樹的資料。另外,由于這裡使用的是異步加載,是以還需要加下面一句:
tree.on('beforeload', function (node)
{
tree.loader.dataUrl = 'region.ejf?cmd=getRegion&id='+(node.id!='root'?node.id:"");
} );
那麼region.ejf?cmd=getRegion是做什麼的呢?就是從資料庫中查詢地區資料,并把他轉換成JSon格式就OK了。下面是RegionAction中的getRegion方法的代碼,如下所示:
public Page doGetRegion(WebForm form)
{
String id=CommUtil.null2String(form.get("id"));
RegionQuery query=new RegionQuery();
query.setPageSize(-1);
if(!"".equals(id))
{
Region parent=this.service.getRegion(new Long(id));
query.setParent(parent);
}
IPageList pageList=this.service.getRegionBy(query);
List<Node> nodes=new java.util.ArrayList<Node>();
for(int i=0;i<pageList.getResult().size();i++)
{
Region region=(Region)pageList.getResult().get(i);
nodes.add(new Node(region));
}
form.addResult("json",AjaxUtil.getJSON(nodes));
return Page.JSONPage;
}
這個代碼說白了,就是根據用戶端的調用參數id值來加載該id下面的地區節點。RegionQuery是一個地區查詢類,主要是我不想寫sql或EJBQL,是以就用他了。大家主要看關鍵的部分,我們在調用service的getRegionBy方法傳回的是一個分頁的地區Entity。是以要把這個地區Entity轉換成與Ext的樹節點資料比對的方式,是以就有了下面一段代碼:
List < Node > nodes = new java.util.ArrayList < Node > ();
for ( int i = 0 ;i < pageList.getResult().size();i ++ )
{
Region region=(Region)pageList.getResult().get(i);
nodes.add(new Node(region));
}
下面我們看看Node這個類的實作,代碼如下:
private class Node
{
private Region region;
Node(Region region)
{
this.region=region;
}
public String getId()
{
return region.getId().toString();
}
public boolean getLeaf()
{
return region.getChildren().size()<1;
}
public String getText()
{
return region.getName();
}
public String getQtip()
{
return region.getName();
}
}
Node直接放在RegionAction中的,是以是Private的。這個Node所做的事就是把伺服器的Region這個域模型适配成Ext的樹狀節點資料。在轉換完以後,我們再看doGetRegion中的最後兩句代碼,如下所示:
form.addResult("json",AjaxUtil.getJSON(nodes));
return Page.JSONPage;
第一句代碼是調用EasyJWeb中的AjaxUtil.getJSON方法直接把nodes這個List生成JSON資料;第二句告訴EasyJWeb這個模闆使用的是JSONPage合成模闆。呵呵,這個Page.JSONPage是這幾天才加上去的,之前釋出的m3沒有,其實JSONPage模闆的内容非常簡單,内容如下:
function(){$!json}()
完成後,把這個Web應用打成war包,然後直接通路tree.html就能看到這個樹了,大緻如下圖所示:
本示例已經被收錄到了EasyJWeb的ajax綜合示例中,裡面還有更多的ajax示例,包括一個表格編輯的應用。
EasyJWeb的ajax綜合示例的位址:http://easyjweb.demo.easyjf.com/ajax2/
本示例War包及源碼:ftp://ftp1.easyjf.com/easyjweb/demo/ajax2.war (13M)
本示例的源碼:ftp://ftp1.easyjf.com/easyjweb/demo/ajax2-src.zip (665K)
注:請下載下傳後将db.properties裡password改為你的密碼。
你更希望我在“一起學ExtJS系列”中跟大家分享哪一方面的内容,請留言