> http://www.meizz.com/ 開發(fā)文檔: http://www.me..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MzTreeView節(jié)點(diǎn)樹(梅花雪)

發(fā)布時(shí)間:2020-08-09 10:51:07 來源:ITPUB博客 閱讀:79 作者:jasonhero 欄目:編程語言
MzTreeView 一次加載數(shù)據(jù)的樹

[@more@]

好東西當(dāng)然要與大家分享。。。@與羊共舞的狼

MzTreeView 1.0 from--->>> http://www.meizz.com/

開發(fā)文檔: http://www.meizz.com/Web/Article.asp?id=436
控件下載: http://www.meizz.com/Web/Download/MzTreeView10.rar
應(yīng)用示例: http://www.meizz.com/Web/Demo/MzTreeView10.htm

說明
MzTreeView 1.0 是數(shù)據(jù)一次性加載,客戶端節(jié)點(diǎn)異步展示的WEB腳本樹。MzTreeView 1.0 的理論節(jié)點(diǎn)數(shù)設(shè)計(jì)上限為十萬節(jié)點(diǎn),在節(jié)點(diǎn)數(shù)三萬的情況下頁面打開時(shí)間小于 3 秒。無限層次無限節(jié)點(diǎn)的數(shù)的層級組成方式:id parentId。即每個(gè)節(jié)點(diǎn)除本身的節(jié)點(diǎn)id之外還有它的父層節(jié)點(diǎn)id,通過這種方式就可以組合成無限層級的樹了。

在 MzTreeView 里都有一個(gè)虛的根節(jié)點(diǎn),其ID為0,用戶可見的根節(jié)點(diǎn)其父節(jié)點(diǎn)ID皆為0

MzTreeView 1.0在數(shù)據(jù)庫庫表里的字段名稱:
字段名字段的具體說明
id節(jié)點(diǎn)ID(不可為0,可以是數(shù)字或字符)
parentId本節(jié)點(diǎn)的父節(jié)點(diǎn)ID(若本節(jié)點(diǎn)已為根節(jié)點(diǎn),此處填0)
text節(jié)點(diǎn)的顯示文本(一般不允許為空,不過有一種情況例外,即根節(jié)點(diǎn),若根節(jié)點(diǎn)文本為空,這個(gè)根節(jié)點(diǎn)將不會(huì)在頁面里顯示)
hint節(jié)點(diǎn)的說明注解
icon節(jié)點(diǎn)的圖標(biāo),MzTreeView 1.0允許每個(gè)節(jié)點(diǎn)擁有不同的圖標(biāo)(對應(yīng)的名字在類里的icons和iconsExpand定義)
data節(jié)點(diǎn)掛的數(shù)據(jù),格式是 param=value¶m=value&... url里?后的那串字符串格式,
url每個(gè)節(jié)點(diǎn)允許擁有不同的鏈接,它為空或者為#時(shí),樹里這個(gè)節(jié)點(diǎn)的鏈接,點(diǎn)擊將無反應(yīng)
target每個(gè)節(jié)點(diǎn)的鏈接允許在不同的target里打開,為空時(shí)取類里的默認(rèn)值
method點(diǎn)擊該鏈接時(shí)所想觸發(fā)的腳本語句
特注:每個(gè)字段值中不可有冒號: 不可以換行 引號酌情考慮應(yīng)不與節(jié)點(diǎn)字符串的引號相沖突
設(shè)計(jì)模式
為了達(dá)到能夠在瀏覽器中快速打開多節(jié)點(diǎn)樹的頁面,我做了很多的優(yōu)化與創(chuàng)新,下面我將詳細(xì)解說幾項(xiàng)最重要的部分:

  • 數(shù)據(jù)一次性加載 首先我要說的就是數(shù)據(jù)的一次性加載。在目前的 B/S 架構(gòu)開發(fā)中對于多節(jié)點(diǎn)多層次的樹,特別是樹節(jié)點(diǎn)量超過兩千的情況下,幾乎都是采取數(shù)據(jù)異步加載來達(dá)到目的,即用戶需要展開某個(gè)節(jié)點(diǎn)時(shí),再從服務(wù)器端加載下級子節(jié)點(diǎn)的數(shù)據(jù),數(shù)據(jù)異步加載最為經(jīng)典的例子就是 MSDN 網(wǎng)站左邊的目錄樹了。異步加載的優(yōu)點(diǎn)在于可以擴(kuò)充到無限級無限節(jié)點(diǎn)樹,樹的數(shù)據(jù)來源可以多樣化(數(shù)據(jù)庫或XML文件)等,但是它的缺點(diǎn)也是非常多的:設(shè)計(jì)模式比數(shù)據(jù)一次性加載要復(fù)雜得多,要考慮到 Browser/Server 之間的應(yīng)答,要判斷子節(jié)點(diǎn)是否含有孫節(jié)點(diǎn),后臺數(shù)據(jù)源的層級關(guān)系模型等。對網(wǎng)絡(luò)傳輸?shù)男刨囆蕴?,每個(gè)節(jié)點(diǎn)的展開都需要連一次 Server,只要在取某節(jié)點(diǎn)數(shù)據(jù)時(shí)網(wǎng)絡(luò)出現(xiàn)問題,就會(huì)導(dǎo)致該節(jié)點(diǎn)及其以下的子節(jié)點(diǎn)加載失敗。而采取數(shù)據(jù)一次加載的模式只要一次加載成功,服務(wù)器就可以不用管它了,服務(wù)器壓力減輕,腳本設(shè)計(jì)則完全獨(dú)立,對整棵樹節(jié)點(diǎn)的檢索可以在客戶端完成,節(jié)點(diǎn)展開響應(yīng)速度快等等優(yōu)勢,因此在節(jié)點(diǎn)數(shù)不多的情況下數(shù)據(jù)一次性加載更有優(yōu)勢,那么這個(gè)節(jié)點(diǎn)數(shù)不多不多到底多少節(jié)點(diǎn)量為平衡點(diǎn)呢?就 ASP.net 里帶的那個(gè) TreeView 來說,在一兩千節(jié)點(diǎn)以下一次性加載比較具有優(yōu)勢,而 MzTreeView 1.0 在節(jié)點(diǎn)量三萬至五萬以非常具有優(yōu)勢。
  • 節(jié)點(diǎn)信息的壓縮傳輸 在瀏覽器里顯示的樹結(jié)構(gòu)其實(shí)都是一個(gè)個(gè) HTML 元素組合起來的,在 WEB 頁面里的樹都是根據(jù)樹節(jié)點(diǎn)的信息組合成一串的 HTML 元素列來顯示,這一步從節(jié)點(diǎn)信息到 HTML 的轉(zhuǎn)化可以在兩個(gè)地方生成:一個(gè)是在服務(wù)器端,一個(gè)是在客戶端。在服務(wù)器端生成的優(yōu)點(diǎn)在于不須考慮客戶端的瀏覽器的兼容性,節(jié)點(diǎn)信息的可控性非常強(qiáng),但是它的缺點(diǎn)也是非常大的:加重服務(wù)器的負(fù)擔(dān),增加網(wǎng)絡(luò)傳輸量。在服務(wù)器端直接生成樹節(jié)點(diǎn)的 HTML 給服務(wù)器帶來的壓力是顯而易見的,也是非常巨大的,估計(jì)只要有幾十個(gè)并發(fā)連接就能讓服務(wù)器暫時(shí)停止響應(yīng)了。這種直接在服務(wù)器生成樹的做法在實(shí)際運(yùn)用環(huán)境中也有人使用,不過本人非常不贊成這種做法。當(dāng)然也有人直接將樹生成為一個(gè)靜態(tài)文件放在服務(wù)器端,這種做法對于樹節(jié)點(diǎn)相對固定不變的情況還是非常有利的,只需要生成一次,以后就不需要再生成了,服務(wù)器的壓力也非常小,但它的弊病在于可變化性太小,比如說不同的權(quán)限能看到的樹節(jié)點(diǎn)的不同這種情況,用這種生成靜態(tài)樹放在服務(wù)器端的做就沒有辦法解決,且不管是服務(wù)器端動(dòng)態(tài)計(jì)算還是直接生成靜態(tài)樹文件放在服務(wù)器端都有一個(gè)避免不了的問題就是網(wǎng)絡(luò)傳輸量巨大??梢杂?jì)算一下,一個(gè)樹點(diǎn)所需要的HTML字符量大約300到600字節(jié)之間。即含有一千節(jié)點(diǎn)的樹的網(wǎng)頁大小就有300K到600K,給網(wǎng)絡(luò)造成的壓力是非常巨大的,所以MzTreeView 1.0采用了節(jié)點(diǎn)信息的壓縮傳輸,大至一千節(jié)點(diǎn)的總傳輸量在30K左右,這可以差了一個(gè)數(shù)量級呀。本樹將每個(gè)節(jié)點(diǎn)所必要的信息組合成一個(gè)字符串序列,傳遞到客戶端,然后在客戶端再用客戶端腳本對這些信息進(jìn)行分析,再生成一個(gè)個(gè)的節(jié)點(diǎn)HTML,這也符合了WEB的分散計(jì)算的原理,當(dāng)然服務(wù)器端可以有選擇性輸出部分節(jié)點(diǎn),這樣又做到節(jié)點(diǎn)的靈活多變性。
  • 傳輸?shù)墓?jié)點(diǎn)信息的可擴(kuò)展性 服務(wù)器端將節(jié)點(diǎn)的必要信息組合成一個(gè)字符串序列傳遞到客戶端,然后客戶端再用腳本對這個(gè)字符串序列進(jìn)行分析,生成樹的節(jié)點(diǎn),那么這個(gè)字符串序列對整個(gè)樹的生成的效率就有重要的影響了。我也參照過很多組串傳輸?shù)睦?,在一般的做法?dāng)中大多采用函數(shù)的參數(shù)方式傳遞。比如說定義一個(gè)函數(shù) funName(p1, p2, p3, ...),然后服務(wù)器組串的時(shí)候就按位置給定數(shù)據(jù)。這種組串的弊病是非常大的,首先就是位置絕對錯(cuò)不得,只要有一個(gè)位置數(shù)據(jù)出錯(cuò),這個(gè)節(jié)點(diǎn)的信息就亂了,對于那些在函數(shù)里已經(jīng)定義的但節(jié)點(diǎn)里沒有的信息也得用空字符串補(bǔ)上,諸如:(p1, "", p3, p4, "", "", ""),且萬一這種組串的對應(yīng)分析函數(shù)發(fā)生了變化,那么這種串就算是廢了,得重新定義服務(wù)器端的字符串位置序列了,可以說這種組串的方式可擴(kuò)展性極差。
    節(jié)點(diǎn)信息組串傳輸?shù)牧硪环N常用模式就是XML。XML以它的無限可擴(kuò)展性已慚有代替HTML稱霸WEB的味道了。XML最大的優(yōu)點(diǎn)就在于它的無限可擴(kuò)展性,可以用任意的TagName名,可以有任意的Attribute名,節(jié)點(diǎn)與子節(jié)點(diǎn)已經(jīng)有層級的關(guān)系,用XML來做WEB樹的數(shù)據(jù)源其實(shí)是最理想的,MSDN的資源目錄樹就是采用XML作為傳遞的字符串,它唯一的不足之處就是不是所有瀏覽器都能很好地支持它,特別是在一些低版本的瀏覽器中,所以我只好忍痛割愛沒有啟用XML作為中間的傳媒。那么是不是有可能結(jié)合XML的擴(kuò)展性對第一種組串的方式進(jìn)行改進(jìn)呢?當(dāng)我愁眉不展的時(shí)候,HTML里的STYLE樣式表寫法跳入我眼,樣式的寫法是"param1: value1; param2: value3; ...",哈哈,這不是現(xiàn)成地給我指明了路嗎?這種寫法擁有XML的可擴(kuò)展性,位置順序的隨意性,又是傳統(tǒng)的長字符串,正合我意也!服務(wù)器給定這種數(shù)據(jù)源字符串,我不光可以在TreeView里用它,還可以直接做Outlook Bar,下拉式層級菜單,右鍵層級菜單的數(shù)據(jù)源,豁然開朗也!我寫了一個(gè)函數(shù)專門解析這種文本:getAttribute()。
  • 客戶端節(jié)點(diǎn)數(shù)據(jù)的存儲方式及快速檢索 現(xiàn)在數(shù)據(jù)源準(zhǔn)備好了,數(shù)據(jù)傳輸也已做到最大優(yōu)化了,下面就是客戶端的腳本解析了,而這一步也正是樹生成的效率瓶頸所在。由于我沒有采用XML做為數(shù)據(jù)源,所以我這里就不討論XML+XSL和XMLDOM的模式,而只考慮HTML+DOM模式了。在HTML+DOM模式下客戶端存儲的方式有很多種,我就曾經(jīng)看到過一種直接將字符串輸出在多行文本框