williamraym

和我一起学ExtJS(二)——树

          最近在学习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,这个完全是一个树的结构,如果把树根砍了话就变成森林了,呵呵这一点跟现实不一样。其它都是settergetter方法,这里就不多说了。

 

然后我们就要做针对这个地区信息的添删除改查了。呵呵,添删改查我最拿手了,特别是基于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>标签,他们是用来引入extjs以及本示例中用到的树。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是一个地区查询类,主要是我不想写sqlEJBQL,所以就用他了。大家主要看关键的部分,我们在调用servicegetRegionBy方法返回的是一个分页的地区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就能看到这个树了,大致如下图所示:

 

 
 

本示例已经被收录到了EasyJWebajax综合示例中,里面还有更多的ajax示例,包括一个表格编辑的应用。

EasyJWebajax综合示例的地址: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系列”中跟大家分享哪一方面的内容,请留言。


posted on 2008-01-10 13:28 WilliamRaym 阅读(3157) 评论(27)  编辑  收藏

评论

# re: 和我一起学ExtJS(二)——树 2008-01-10 13:53 beans

不错,希望能有更详细的介绍。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 13:58 WilliamRaym

不知道你所指的更详细的介绍是要哪方面的?  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 15:01 xidudui

不错的东东  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 16:37 beans

@WilliamRaym
关于ExtJS部分的代码说明少了,另外我看了你们的示例,我觉得那个客户档案表格的应用做得不错,非常有参考价值。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 17:09 久城

BZ是EasyJWeb的成员吗?
我之前对EasyJWeb并不是很了解,看了看你们的网站,很不错。

文中用到AjaxUtil.getJSON(nodes),是调用EasyJWeb中的AjaxUtil.getJSON方法直接把nodes这个List生成JSON数据。

这几天学习Extjs,一直对如何把List转换成一个JSON对象传递给客户端有些迷惑。下午用JSON-RPC这个包中的JSONObject类实验了一下,结合Extjs中的JsonReader总是解析的时候有些偏差。

很想听听BZ对如何把List转换成一个JSON对象传递给客户端的看法,目前好像有很多开源的包都可以实现。以BZ的经验希望指点一二。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 17:34 WilliamRaym

EasyJWeb框架中内置了一个支持远程脚本调用的引擎,见大峡同学的一篇文章http://www.easyjf.com/blog/html/20080103/1015816.html,而个AjaxUtil.getJSON这个方法正是那个引擎中提供的一个小具,不像一般简单的JSON转换,这个转换功能是比较强的,支持深层次的转换。如果转换一个顶级的地区,比如“中国”,假如中国下面有一个子节点“北京”,那么下面的代码可以展示这个特点:
form.addResult("root",AjaxUtil.getJSON(root));
return Page.JSONPage

在客户端使用下面的代码:
var o=eval(req.responseText);
alert(o.children[0].parent.children[1].parent.name) 输出“中国”
alert(o.children[0].name) 输出“北京”
  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 18:04 久城

@WilliamRaym
谢谢指点~!~:)
问题是我现在需要这样一个能够实现转换的类包,但是又不想把整个EasyJWeb框架都套过来。不知道AjaxUtil这个类是否可以脱离框架独立使用?
而且针对我的这个需求,应用AjaxUtil这个类是否合适?(因为我没有用过其它的,而这个AjaxUtil类我也不是很清楚有多大)
BZ能再谈谈吗?再次谢谢......  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 18:07 WilliamRaym

AjaxUtil是我们在工作中总结出来的一些实用的工具,你可以只用它转换的部分代码,而且可喜的是easyjweb只有几百K,最好是结合easyjweb起使用,如果不清楚如何用easyjweb,可以看看这个视频http://www.easyjf.com/blog/html/20080102/1015814.html。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 18:09 久城

@WilliamRaym
well , thanks again !~  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 18:10 WilliamRaym

you are welcome!  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-10 20:47 黄狼很暴力

虽然看到最后就知道是在推广EasyJWeb,但是这样比较让人可以接受,比其他枪手贴好多了  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-11 08:34 sitinspring

关注一下。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-11 11:38 哥哥的弟弟

最新版本的Easyjweb是1.0-m3版吗?  回复  更多评论   

# re: 和我一起学ExtJS(二)——树[未登录] 2008-01-11 11:44 WilliamRaym

也可以从SVN上checkout最新代码http://svn.easyjf.com/repos/easyjweb/trunk/  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-11 11:45 lengyu

@ 哥哥的弟弟

对。。  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-12 16:45 小白之家

ExtJS好象很多语言都可以用啊,也扯上了ajax,blog主是EasyJWeb的大牛?
看blog写的文章,还不错,特别有事例,很开心  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:47 征途私服

1719  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:47 传世私服

6064  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:47 传奇世界私服

4989  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:48 魔兽世界私服

8883  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:48 魔兽世界私服

3008  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:48 魔兽世界私服

1813  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:49 魔兽私服

7046  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:49 魔兽私服

8256  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 13:49 魔兽私服

0832  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2008-01-14 15:25 哥哥的弟

支持就两个字  回复  更多评论   

# re: 和我一起学ExtJS(二)——树 2010-06-18 16:10 Rosanu

有没有用ASP.NET写的啊???  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2008年1月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(6)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜