williamraym

          和我一起學(xué)ExtJS(二)——樹

          ??????????最近在學(xué)習(xí)ExtJS,發(fā)現(xiàn)其服務(wù)器端是php,這一點(diǎn)對(duì)我們搞java的有點(diǎn)不厚道啊。昨天學(xué)習(xí)了ExtJS的樹,并做了一棵異步更新的樹出來(lái),后臺(tái)的業(yè)務(wù)邏輯及持久層使用JPA+Spring2.5實(shí)現(xiàn),發(fā)下面把步驟貼出來(lái)與大家分享。

            

          首先準(zhǔn)備樹的域模型,下面是一地區(qū)的域模型對(duì)象, 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,這個(gè)完全是一個(gè)樹的結(jié)構(gòu),如果把樹根砍了話就變成森林了,呵呵這一點(diǎn)跟現(xiàn)實(shí)不一樣。其它都是settergetter方法,這里就不多說(shuō)了。

          ?

          然后我們就要做針對(duì)這個(gè)地區(qū)信息的添刪除改查了。呵呵,添刪改查我最拿手了,特別是基于EJS(EasyJWeb+JPA+Spring2)構(gòu)架的添刪改查,一個(gè)命令搞定了。這里就不多說(shuō)了,大家可以直接看我前段時(shí)間做的視頻演示(http://www.easyjf.com/blog/html/20080102/1015814.html)。當(dāng)然這個(gè)示例由于是分級(jí)別的,所以生成的添刪改查還要改一改,才支持上下級(jí)管理功能。

          ?

          下面進(jìn)入我們重點(diǎn)部分,如何在頁(yè)面中得到一棵表示地區(qū)的樹。

          首先準(zhǔn)備一個(gè)tree.html,內(nèi)容如下:

          <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>

          ?

          注意幾個(gè)<script>標(biāo)簽,他們是用來(lái)引入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:?'地區(qū)信息',
          ????????draggable:
          false,
          ????????id:'root'
          ????}
          );
          ????tree.setRootNode(root);
          ????tree.render();
          ???????root.expand();
          }
          );

          ?

          其實(shí)tree.js的代碼跟ExtJS官方示例中的差別不大,這里就不對(duì)這個(gè)代碼作詳細(xì)的解釋,如果你感興趣的話,可以在后面留言或給我發(fā)電子郵件。如果需要的人多的話,我看能否補(bǔ)充。這里把重點(diǎn)的代碼強(qiáng)調(diào)一下。


          loader:?new?Ext.tree.TreeLoader({
          ????????????dataUrl:'region.ejf
          ?cmd=getRegion'????????????
          ????????}
          )

          ?

          這個(gè)表示通過(guò)region.ejf?cmd=getRegion來(lái)加載樹的數(shù)據(jù)。另外,由于這里使用的是異步加載,所以還需要加下面一句:


          tree.on('beforeload',function(node){????????
          ????????????tree.loader.dataUrl?
          =?'region.ejf?cmd=getRegion&id='+(node.id!='root'?node.id:"");
          ????????}
          );??

          ?

          那么region.ejf?cmd=getRegion是做什么的呢?就是從數(shù)據(jù)庫(kù)中查詢地區(qū)數(shù)據(jù),并把他轉(zhuǎn)換成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;
          ????}


          ?

          這個(gè)代碼說(shuō)白了,就是根據(jù)客戶端的調(diào)用參數(shù)id值來(lái)加載該id下面的地區(qū)節(jié)點(diǎn)。RegionQuery是一個(gè)地區(qū)查詢類,主要是我不想寫sqlEJBQL,所以就用他了。大家主要看關(guān)鍵的部分,我們?cè)谡{(diào)用servicegetRegionBy方法返回的是一個(gè)分頁(yè)的地區(qū)Entity。所以要把這個(gè)地區(qū)Entity轉(zhuǎn)換成與Ext的樹節(jié)點(diǎn)數(shù)據(jù)匹配的方式,因此就有了下面一段代碼:

          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這個(gè)類的實(shí)現(xiàn),代碼如下:


          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的。這個(gè)Node所做的事就是把服務(wù)器的Region這個(gè)域模型適配成Ext的樹狀節(jié)點(diǎn)數(shù)據(jù)。在轉(zhuǎn)換完以后,我們?cè)倏?/span>doGetRegion中的最后兩句代碼,如下所示:

          ??? form.addResult("json",AjaxUtil.getJSON(nodes));

          ??? return Page.JSONPage;

          第一句代碼是調(diào)用EasyJWeb中的AjaxUtil.getJSON方法直接把nodes這個(gè)List生成JSON數(shù)據(jù);第二句告訴EasyJWeb這個(gè)模板使用的是JSONPage合成模板。呵呵,這個(gè)Page.JSONPage是這幾天才加上去的,之前發(fā)布的m3沒(méi)有,其實(shí)JSONPage模板的內(nèi)容非常簡(jiǎn)單,內(nèi)容如下:

          function(){$!json}()

          ?

          完成后,把這個(gè)Web應(yīng)用打成war包,然后直接訪問(wèn)tree.html就能看到這個(gè)樹了,大致如下圖所示:

          ?

          ?
          ?

          本示例已經(jīng)被收錄到了EasyJWebajax綜合示例中,里面還有更多的ajax示例,包括一個(gè)表格編輯的應(yīng)用。

          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)

          ?注:請(qǐng)下載后將db.properties里password改為你的密碼。

          你更希望我在“一起學(xué)ExtJS系列”中跟大家分享哪一方面的內(nèi)容,請(qǐng)留言。


          posted on 2008-01-10 13:28 WilliamRaym 閱讀(3181) 評(píng)論(27)  編輯  收藏

          評(píng)論

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 13:53 beans

          不錯(cuò),希望能有更詳細(xì)的介紹。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 13:58 WilliamRaym

          不知道你所指的更詳細(xì)的介紹是要哪方面的?  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 15:01 xidudui

          不錯(cuò)的東東  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 16:37 beans

          @WilliamRaym
          關(guān)于ExtJS部分的代碼說(shuō)明少了,另外我看了你們的示例,我覺(jué)得那個(gè)客戶檔案表格的應(yīng)用做得不錯(cuò),非常有參考價(jià)值。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 17:09 久城

          BZ是EasyJWeb的成員嗎?
          我之前對(duì)EasyJWeb并不是很了解,看了看你們的網(wǎng)站,很不錯(cuò)。

          文中用到AjaxUtil.getJSON(nodes),是調(diào)用EasyJWeb中的AjaxUtil.getJSON方法直接把nodes這個(gè)List生成JSON數(shù)據(jù)。

          這幾天學(xué)習(xí)Extjs,一直對(duì)如何把List轉(zhuǎn)換成一個(gè)JSON對(duì)象傳遞給客戶端有些迷惑。下午用JSON-RPC這個(gè)包中的JSONObject類實(shí)驗(yàn)了一下,結(jié)合Extjs中的JsonReader總是解析的時(shí)候有些偏差。

          很想聽(tīng)聽(tīng)BZ對(duì)如何把List轉(zhuǎn)換成一個(gè)JSON對(duì)象傳遞給客戶端的看法,目前好像有很多開(kāi)源的包都可以實(shí)現(xiàn)。以BZ的經(jīng)驗(yàn)希望指點(diǎn)一二。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 17:34 WilliamRaym

          EasyJWeb框架中內(nèi)置了一個(gè)支持遠(yuǎn)程腳本調(diào)用的引擎,見(jiàn)大峽同學(xué)的一篇文章http://www.easyjf.com/blog/html/20080103/1015816.html,而個(gè)AjaxUtil.getJSON這個(gè)方法正是那個(gè)引擎中提供的一個(gè)小具,不像一般簡(jiǎn)單的JSON轉(zhuǎn)換,這個(gè)轉(zhuǎn)換功能是比較強(qiáng)的,支持深層次的轉(zhuǎn)換。如果轉(zhuǎn)換一個(gè)頂級(jí)的地區(qū),比如“中國(guó)”,假如中國(guó)下面有一個(gè)子節(jié)點(diǎn)“北京”,那么下面的代碼可以展示這個(gè)特點(diǎn):
          form.addResult("root",AjaxUtil.getJSON(root));
          return Page.JSONPage

          在客戶端使用下面的代碼:
          var o=eval(req.responseText);
          alert(o.children[0].parent.children[1].parent.name) 輸出“中國(guó)”
          alert(o.children[0].name) 輸出“北京”
            回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 18:04 久城

          @WilliamRaym
          謝謝指點(diǎn)~!~:)
          問(wèn)題是我現(xiàn)在需要這樣一個(gè)能夠?qū)崿F(xiàn)轉(zhuǎn)換的類包,但是又不想把整個(gè)EasyJWeb框架都套過(guò)來(lái)。不知道AjaxUtil這個(gè)類是否可以脫離框架獨(dú)立使用?
          而且針對(duì)我的這個(gè)需求,應(yīng)用AjaxUtil這個(gè)類是否合適?(因?yàn)槲覜](méi)有用過(guò)其它的,而這個(gè)AjaxUtil類我也不是很清楚有多大)
          BZ能再談?wù)剢幔吭俅沃x謝......  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 18:07 WilliamRaym

          AjaxUtil是我們?cè)诠ぷ髦锌偨Y(jié)出來(lái)的一些實(shí)用的工具,你可以只用它轉(zhuǎn)換的部分代碼,而且可喜的是easyjweb只有幾百K,最好是結(jié)合easyjweb起使用,如果不清楚如何用easyjweb,可以看看這個(gè)視頻http://www.easyjf.com/blog/html/20080102/1015814.html。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 18:09 久城

          @WilliamRaym
          well , thanks again !~  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 18:10 WilliamRaym

          you are welcome!  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-10 20:47 黃狼很暴力

          雖然看到最后就知道是在推廣EasyJWeb,但是這樣比較讓人可以接受,比其他槍手貼好多了  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-11 08:34 sitinspring

          關(guān)注一下。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-11 11:38 哥哥的弟弟

          最新版本的Easyjweb是1.0-m3版嗎?  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹[未登錄](méi) 2008-01-11 11:44 WilliamRaym

          也可以從SVN上checkout最新代碼http://svn.easyjf.com/repos/easyjweb/trunk/  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-11 11:45 lengyu

          @ 哥哥的弟弟

          對(duì)。。  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-12 16:45 小白之家

          ExtJS好象很多語(yǔ)言都可以用啊,也扯上了ajax,blog主是EasyJWeb的大牛?
          看blog寫的文章,還不錯(cuò),特別有事例,很開(kāi)心  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:47 征途私服

          1719  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:47 傳世私服

          6064  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:47 傳奇世界私服

          4989  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:48 魔獸世界私服

          8883  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:48 魔獸世界私服

          3008  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:48 魔獸世界私服

          1813  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:49 魔獸私服

          7046  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:49 魔獸私服

          8256  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 13:49 魔獸私服

          0832  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2008-01-14 15:25 哥哥的弟

          支持就兩個(gè)字  回復(fù)  更多評(píng)論   

          # re: 和我一起學(xué)ExtJS(二)——樹 2010-06-18 16:10 Rosanu

          有沒(méi)有用ASP.NET寫的啊???  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2008年1月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 遂溪县| 保山市| 通渭县| 嵊泗县| 昌吉市| 富阳市| 建昌县| 容城县| 三台县| 鹤峰县| 丰县| 依安县| 灌南县| 万源市| 屏南县| 丹东市| 犍为县| 鸡西市| 神农架林区| 武平县| 西乌| 石屏县| 澜沧| 无为县| 丰城市| 教育| 磴口县| 湘潭县| 简阳市| 夹江县| 盐源县| 普安县| 永川市| 永胜县| 比如县| 仁化县| 海宁市| 南皮县| 祁阳县| 呼玛县| 昌吉市|