iNeo

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            30 Posts :: 8 Stories :: 2 Comments :: 0 Trackbacks
          2.3 業(yè)務(wù)邏輯層設(shè)計(jì)

            2.3.1 動(dòng)態(tài)加載技術(shù)

            如果一次性獲取完整的先序樹(shù),構(gòu)造成xml提供給JavaScript解析,數(shù)據(jù)量越大,消耗的資源越多,客戶端響應(yīng)延遲時(shí)間就越長(zhǎng),因此對(duì)于大數(shù)據(jù)量的樹(shù),采用動(dòng)態(tài)加載方式,即每次單擊“+”圖片時(shí),判斷是否已加載子節(jié)點(diǎn)數(shù)據(jù),如果未加載則通過(guò)Ajax的XMLHTTP組件XMLHTTPRequest對(duì)象異步發(fā)送請(qǐng)求,連接服務(wù)器執(zhí)行SQL 語(yǔ)句“select * from tree_class where parent = ?order by classcode ”獲取節(jié)點(diǎn)數(shù)據(jù)。相關(guān)JavaScript 代碼如下:

          /*判斷是否已經(jīng)加載數(shù)據(jù),未加載則訪問(wèn)服務(wù)器加載數(shù)據(jù)*/

          dhtmlTree.prototype.Loading=function(pObject){
           if(((pObject.XMLload==0)&&(this.XMLsource))&&(!this.XMLloading)){
            pObject.XMLload=1;
            this.loadXML(this.XMLsource+getUrlSymbol(this.XMLsource)+"id="+escape(pObject.id));
           }
          }
          dtmlXMLObject.prototype.loadXML=function(url){//加載數(shù)據(jù)
           try {
            this.xmlDoc = new XMLHttpRequest();
            /*通過(guò)GET方法異步連接到 url 加載數(shù)據(jù)*/
            this.xmlDoc.open("GET", url,true);//true:異步;false:同步
            this.xmlDoc.send(null);
           } catch(e){
            this.xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");//使用IE
            this.xmlDoc.open("GET", url,true);//true:異步;false:同步
            this.xmlDoc.send(null);
           }
           return this.xmlDoc.responseXML;
          }

            每次只取同一個(gè)父節(jié)點(diǎn)ParentId的子節(jié)點(diǎn)序列,按XML格式封裝成樹(shù)的文檔結(jié)構(gòu),例如:

          <tree id="0">
          <leaf child=”1" name="國(guó)防科技大學(xué)" id="1" im0="leaf.gif" im1="folderOpen.gif" im2=" folderClosed.gif"/>
          </tree>

            提供給JavaScript的dhtmlTreeObject.prototype.insertItem()解析并組織好html輸出節(jié)點(diǎn);其中 child:1表示有子節(jié)點(diǎn),0表示沒(méi)有子節(jié)點(diǎn);im0表示沒(méi)有子節(jié)點(diǎn)時(shí)的圖標(biāo);im1表示有子節(jié)點(diǎn)并且打開(kāi)節(jié)點(diǎn)時(shí)的圖標(biāo);im2表示有子節(jié)點(diǎn)并且關(guān)閉時(shí)的圖標(biāo);所以還可以在構(gòu)造XML時(shí)自定義圖標(biāo)。

            2.3.2 樹(shù)型結(jié)構(gòu)的構(gòu)造

            從數(shù)據(jù)庫(kù)中返回的是有序的先序樹(shù),而XML是完整的樹(shù)型結(jié)構(gòu)文檔,所以將樹(shù)型數(shù)據(jù)構(gòu)造成預(yù)定義的XML格式,只需從根節(jié)點(diǎn)開(kāi)始,遍歷一遍樹(shù),即可將樹(shù)全部生成。相關(guān)JavaScript代碼如下:

          /*動(dòng)態(tài)加載樹(shù)的構(gòu)造方法*/

          dtmlXMLObject.prototype.constructTree=function(){

          //采用動(dòng)態(tài)加載時(shí)獲取的xml數(shù)據(jù),解析樹(shù)型數(shù)據(jù)

          var node=this.XMLLoader.getXMLTopNode("tree");

          var parentId=node.getAttribute("id");

          for(var i=0;i<node.childNodes.length;i++) { //逐個(gè)解析xml文件的leaf節(jié)點(diǎn)

           if((node.childNodes[i].nodeType==1)&&(node.childNodes[i].tagName == "leaf")){
            var name=node.childNodes[i].getAttribute("text");
            …………
            var temp=dhtmlObject.a0Find(parentId);//獲取父節(jié)點(diǎn)對(duì)象
            temp.XMLload=1;//已加載
            //構(gòu)造html輸出節(jié)點(diǎn)
            dhtmlObject.insertItem(parentId,cId,name,im0,im1,im2,chd);
            dhtmlObject.addDragger = this;//設(shè)置可拖放的對(duì)象
           };
          }

            2.3.3 樹(shù)型結(jié)構(gòu)的維護(hù)

            在維護(hù)樹(shù)型結(jié)構(gòu)表時(shí),刪除節(jié)點(diǎn)較為簡(jiǎn)單,SQL 語(yǔ)句為: "delete from tree_class where classcode like′"+ classcode +"%′",即可將其節(jié)點(diǎn)和孩子一并刪除;增加節(jié)點(diǎn)時(shí),分為前插、后插、和插入子節(jié)點(diǎn)三種情況,前兩種情況需要更新遞歸更新類別代碼,后者只需找到父節(jié)點(diǎn)的孩子的最大類別代碼加1 后,作為增加節(jié)點(diǎn)的類別代碼;通過(guò)拖放來(lái)改變樹(shù)的結(jié)構(gòu)時(shí),只需將拖動(dòng)節(jié)點(diǎn)的parentId更新為目標(biāo)節(jié)點(diǎn)的Classid即可,對(duì)應(yīng)的SQL語(yǔ)句為:"update tree_class set parentId = "+ classidTo+" where classid = "+ classidFrom。

            3、效率分析

            對(duì)于樹(shù)的存儲(chǔ)一般有兩種形式:二維表和鏈表,遍歷方式一般也有深度遍歷和廣度遍歷兩種方式,遍歷的時(shí)間復(fù)雜度都是O( n )。用二維表存儲(chǔ)時(shí),在內(nèi)存中用數(shù)組的下標(biāo)能準(zhǔn)確定位節(jié)點(diǎn)的父節(jié)點(diǎn)、兄弟節(jié)點(diǎn)所在的數(shù)組下標(biāo)。數(shù)據(jù)庫(kù)中節(jié)點(diǎn)的定位也是準(zhǔn)確的,但是將節(jié)點(diǎn)信息從數(shù)據(jù)庫(kù)中讀到內(nèi)存中時(shí),如果無(wú)法通過(guò)內(nèi)存數(shù)組下標(biāo)定位節(jié)點(diǎn)信息,那么就必須遍歷一遍尋找一個(gè)節(jié)點(diǎn),n 個(gè)節(jié)點(diǎn)中尋找一個(gè)節(jié)點(diǎn)的時(shí)間是O(n/2),n 個(gè)節(jié)點(diǎn)排序的時(shí)間復(fù)雜度將是O( n 2/2),這也是一般實(shí)現(xiàn)的B/S 模式的樹(shù)結(jié)構(gòu)效率低下的原因。本方案采用字典序編號(hào)方案,使得從數(shù)據(jù)庫(kù)中取得的樹(shù)是已經(jīng)排序的,直接遍歷生成客戶頁(yè)面程序,時(shí)間復(fù)雜度為O( n )。

            4、結(jié) 論

            本文討論了基于Ajax的動(dòng)態(tài)樹(shù)型結(jié)構(gòu)的實(shí)現(xiàn)方案,支持無(wú)刷新動(dòng)態(tài)維護(hù)樹(shù)的節(jié)點(diǎn)信息,支持拖放節(jié)點(diǎn)改變樹(shù)的節(jié)點(diǎn)結(jié)構(gòu)以及次序;同時(shí)采用數(shù)據(jù)庫(kù)存儲(chǔ)節(jié)點(diǎn)信息,保證了該方案有一定的通用性,此外結(jié)合XML描述樹(shù)的節(jié)點(diǎn)信息,使得任何按本方案預(yù)定的xml文檔描述的信息都可以通過(guò)樹(shù)來(lái)展現(xiàn)。本方案已經(jīng)應(yīng)用在我校的數(shù)字迎新系統(tǒng)以及老百姓大藥房信息系統(tǒng)中。

          posted on 2005-12-30 08:32 只牽這只狗 閱讀(395) 評(píng)論(0)  編輯  收藏 所屬分類: Ajax
          主站蜘蛛池模板: 松滋市| 明溪县| 高安市| 浙江省| 平利县| 景泰县| 调兵山市| 密山市| 凤阳县| 邳州市| 库尔勒市| 东阳市| 旅游| 屏山县| 孟津县| 保德县| 平乐县| 海安县| 萨嘎县| 哈尔滨市| 花莲市| 全椒县| 溆浦县| 中超| 青阳县| 广宁县| 县级市| 湟源县| 府谷县| 阿尔山市| 休宁县| 鄂州市| 綦江县| 获嘉县| 文成县| 平乡县| 临桂县| 虹口区| 铜川市| 阜宁县| 三都|