posts - 11, comments - 29, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理

          ***************************************
          關(guān)鍵字:AJAX,Tree,Struts,DOM
          難易度:
          軟件版本:struts 1.2.8
          時間:2006-01-27
          Author:Kino
          ***************************************


          前陣子寫了一個小代碼處理AJAX下WebTree的構(gòu)建,其中碰到了一些問題,也有一些想法,現(xiàn)在說出來希望大家一起看看,如果案由問題請不吝賜教,本人不勝感激啊。

          背景:
          這次因?yàn)槭羌虞d在Struts上的開發(fā),Web頁面上的Tree作AJAX處理,因?yàn)橛蠳ode的增刪改操作。Server端因?yàn)橐蚖ebService連接,所以不做Cache。

          解決案:
          1。使用Polling調(diào)用AJAX定期更新Tree。
          2。AJAX訪問的地址是一個Action(例:createtree.do)。用來返回Tree模型或者錯誤消息(國際化)。
          3。Browser解析XML的TreeModel。
          4。在Browser比較新舊2個TreeModel,完成選中狀態(tài)的繼承。
          5。CSS渲染TreeNode。

          以上是簡單的思路。傳統(tǒng)的AJAX應(yīng)該是盡量減少XMl傳輸量,迫于沒有Cache的緣故,并且WS給我的節(jié)點(diǎn)并不能簡單的得到父子關(guān)系。我選擇了,每次Polling更新整棵樹的方案。性能未測。

          我這次在web server 端構(gòu)建Tree時直接用深度優(yōu)先轉(zhuǎn)換成XML。XMl中數(shù)據(jù)的先后順序決定了Tree從父到子,從兄到弟的深度優(yōu)先關(guān)系,indent決定了深度(也就是縮進(jìn))。這樣我從Server端傳入的也就成了一個標(biāo)準(zhǔn)的Tree顯示Model。格式定義如下。
            * Gobal Master Tree DTD
           * &lt!ELEMENT tree (tree*)&gt
           * &lt!ATTLIST tree
           *  id   CDATA #REQUIRED LoctionInfo's toString
           *  indent  CDATA #REQUIRED Tree's Level
           *  text        CDATA   #REQUIRED label in html
           *  tooltip     CDATA   #IMPLIED title in html
           *  action      CDATA   #IMPLIED href in html
           *  icon        CDATA   #IMPLIED close icon with the node status
           *  openicon    CDATA   #IMPLIED open icon with the node status
           *  open        CDATA   #IMPLIED&gt node's open states ,default is false in server.
           *  target  CDATA #IMPLIED node's open target
           *
          <span id="maintree">
           <tree id="Ajax" indent=0 text="Root" tooltip="Root" action="/logout.do" icon="" openicon= "" open="false"/>
           <tree id="110" indent=1 text="Node 1" tooltip="Node 1" action="/logout.do" icon="" openicon= "" open="false"/>
           <tree id="120" indent=2 text="Node 2" tooltip="Node 2" action="/logout.do" icon="" openicon= "" open="false"/>
           <tree id="12580" indent=2 text="Node 3" tooltip="Node 3" action="/logout.do" icon="" openicon= "" open="false"/>
           <tree id="user" indent=1 text="Node 4" tooltip="Node 4" action="/logout.do" icon="" openicon= "" open="false"/>
          </span>

          上邊的 Tree顯示出來如下
          Root
           │
           ├Node 1
           │    │
           │    ├Node 2
           │    └Node 3
           └Node 4
          indent   就是縮進(jìn)。
          數(shù)據(jù)的先后順序就是深度優(yōu)先的遍歷順序。

          這樣的數(shù)據(jù)到了Browser,會先被轉(zhuǎn)成一個對象數(shù)組。

           1// Tree Node object
           2// This function creates a node in the tree with the following arguments:
           3//    sId         - The node's index within the global nodes_array
           4//    iIndent    - The level within the tree hierarchy (0 = top)
           5//    sText      - The text displayed in the tree for this node
           6//    sTooltip     - the tool tip
           7//    oAction   - For a document, the address it will display when clicked
           8//    sIcon        - the node's icon 
           9//    sIconOpen    - the node's icon state
          10//      bOpen - true  false
          11function GMTreeNode(sId,iIndent,sText,sTooltip,sAction,sIcon,sIconOpen,bOpen,sTarget)
          12{
          13    if (sId) this.id = sId;
          14    if (iIndent) this.indent = iIndent;
          15    if (sText) this.text = sText;
          16    if (sAction) this.action = sAction;
          17    if (sTooltip) this.tooltip = sTooltip;
          18    if (sIcon) this.icon = sIcon;
          19    if (sIconOpen) this.iconopen = sIconOpen;
          20    if (bOpen) this.open = bOpen;
          21    if (sTarget) this.target = sTarget;
          22    
          23//    //alert(this.id + "  " + this.indent + "  " + this.text + "  " + this.action + "  " + 
          24//    this.tooltip + "  " + this.icon + "  " + this.iconopen + "  " + this.open);
          25}

          然后會和正在顯示的Tree數(shù)組 進(jìn)行一個 比較,用于寫入展開狀態(tài),代碼如下:
           1/////////////////////////////////
           2//    >>>Compare 
           3//    compare maintree with maintree. and copy maintree to maintree
           4/////////////////////////////////
           5function compareTreeModel()
           6{
           7    //alert("I am here in compareTreeModel");
           8    if (ajaxtree.length <= 0){
           9        alert("ajaxtree is null");//TODO
          10        return;
          11    }

          12    
          13    if (maintree.length <= 0){
          14        //alert("maintree is null");
          15        maintree = ajaxtree;
          16        return;
          17    }

          18    //compare start
          19    //var maxlen = Math.max(ajaxtree.length,maintree.length);
          20    for(var i=0;i<ajaxtree.length;i++)
          21    {
          22        for(var j=0;j<maintree.length;j++)
          23        {
          24            if (ajaxtree[i].id == maintree[j].id)
          25            {
          26                ajaxtree[i].open = maintree[j].open;
          27                break;
          28            }

          29        }
              
          30    }

          31    
          32    maintree = ajaxtree;
          33    
          34}
          maintree 就是正在顯示的 Tree,ajaxtree是剛得到的新Tree。2個對象都是TreeNode的數(shù)組。而TreeNode對象的Open屬性即記錄了節(jié)點(diǎn)的展開狀態(tài)。那么這里就對這個節(jié)點(diǎn)狀態(tài)進(jìn)行“移植”,完畢后,把新Tree模型交付顯示方法,也就是ToHtml方法。

          轉(zhuǎn)換Html部分算是一個比較容易出bug的危險(xiǎn)點(diǎn)。

          首先分析一下,生成的代碼是什么樣子的。
          這里仍然用上邊的那棵樹作例子。
          生成的DOM結(jié)構(gòu)應(yīng)該是
          <div 父>
              <div  收縮>
              <img  折線  />
              <img  圖標(biāo) />
              <a 節(jié)點(diǎn)動作>節(jié)點(diǎn)Label</a>
              <div 子>
                  ....遞歸的構(gòu)造
              </div 子>
              </div 收縮>
          </div 父>

          其次 對于這種并不直接含有父子關(guān)系的節(jié)點(diǎn)首先要判明一個節(jié)點(diǎn)的子 和 兄弟,然后用遞歸解決。
          遞歸的思路如下深度優(yōu)先:
          function toHtml(節(jié)點(diǎn)index)
          {
             var child_html;
             if 這個節(jié)點(diǎn)有子
             {
                  Loop子節(jié)點(diǎn)
                  {
                         child_html[i] = toHtml(子節(jié)點(diǎn)index);
                         i++;訪問下一個子節(jié)點(diǎn)
             }
            
             var 所有子節(jié)點(diǎn)Html模塊 = <div 收縮>   child_html.join("") </div>

             var 本節(jié)點(diǎn)Html模塊 = <div 本節(jié)點(diǎn)><div 收縮><img ><img  圖標(biāo) /><a 節(jié)點(diǎn)動作>節(jié)點(diǎn)Label</a>所有子節(jié)點(diǎn)Html模塊</div 收縮></div 本節(jié)點(diǎn)>;

             return  本節(jié)點(diǎn)Html模塊;
          }

          樹就構(gòu)建好了。

          作為顯示,使用了CSS的
          background-repeat: repeat-y;
           background-image: url("../images/tree/I.png") !important;
           background-position-y: 1px !important; /* IE only */

          還有padding-left作Div的向右偏移,默認(rèn)的偏移量是19個像素點(diǎn),然后根據(jù)Tree顯示模型的indent相乘就ok了。

          思路就是這些。希望能對 朋友們有所幫助。
          歡迎討論。

          評論

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2006-03-15 10:16 by 甲蟲
          您好,很榮幸看到這個,也非常的高興,在網(wǎng)上找到很多卻沒有找到類似的,請您幫我一個忙,能不能把這個AJAX Web Tree 的完整的例子發(fā)給我一份,將不勝感激.
          我的Email:sf1979@gmail.com
          再次感謝!

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2006-03-15 10:59 by 小葉
          不知道有沒有ASP版的?我也想學(xué)這個呢:)

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2006-03-29 22:35 by kino
          sorry 最近工作問題比較忙。很久沒有來更新了。我這兩天會給sf1979@gmail.com留下代碼的。如果你修改了代碼也請告訴我,做個交流好么。
          如果想及時聯(lián)系我請Mail To:kinoviti@gmail.com

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2007-04-13 17:55 by
          您好,很榮幸看到這個,在網(wǎng)上找到很多z至今還沒有找到合適的,能不能把你這個AJAX Web Tree 的完整的例子發(fā)給我一份,不勝感激.
          Email:guowei.hj@gmail.com
          謝謝!

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2007-04-13 18:01 by
          真的 非常 謝謝!

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2007-10-17 18:01 by siyuan
          非常好可以把完整代碼發(fā)給我嗎?
          我的Email:wjl_2007@sina.com
          謝謝

          # re: AJAX Web Tree 構(gòu)建方案及實(shí)現(xiàn)思想  回復(fù)  更多評論   

          2008-07-01 10:40 by dmm
          非常好可以把完整代碼發(fā)給我嗎?
          我的Email:dongming_9431@163.com
          謝謝

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 鄱阳县| 辰溪县| 内丘县| 岑溪市| 县级市| 申扎县| 怀远县| 巴塘县| 长武县| 定边县| 崇礼县| 山西省| 金山区| 永康市| 东山县| 昔阳县| 乌兰县| 习水县| 海口市| 上高县| 平乡县| 新源县| 双峰县| 江山市| 怀柔区| 芒康县| 长泰县| 瑞丽市| 三明市| 榕江县| 海伦市| 西平县| 井陉县| 望奎县| 金沙县| 昂仁县| 永宁县| 平利县| 芒康县| 永靖县| 昭通市|