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 閱讀(3181) 評論(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)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 龙泉市| 西乌珠穆沁旗| 泸溪县| 名山县| 读书| 龙井市| 丰城市| 临澧县| 德江县| 郸城县| 靖江市| 彩票| 尉犁县| 揭阳市| 兖州市| 汾阳市| 拉萨市| 分宜县| 吴桥县| 楚雄市| 鹤峰县| 新民市| 嘉善县| 理塘县| 台北市| 应城市| 惠州市| 九龙城区| 丽水市| 平湖市| 博兴县| 利津县| 屯昌县| 米易县| 龙里县| 孟津县| 南汇区| 灵丘县| 阿合奇县| 嘉义市| 湘乡市|