)用Ajax技術讓IE Web Control Tree View實現大資料量讀取

來源:互聯網
上載者:User
轉自:http://www.cnblogs.com/dingsea/archive/2005/10/26/262220.html相信不少人都用過微軟提供的一款控制項: IEControl,
其中的TreeView使用比較廣泛。在我參與的一個項目中,一個名為UNSPSC的模組將頻繁使用這個控制項。這個控制項在一般情況下相當好用(節點小於200個),但當節點數比較多時將使用戶端長時間等待,大資料量時會讓用戶端逾時以至於讀取失敗。本模組在進行壓力測試時,資料庫中有24000多條記錄,一次性讀取出來將使IE死掉,這自然不能適用於對UNSPSC的讀取(UNSPSC要求最多支援9000萬條記錄)。於是我想使用Ajax(Asynchronous
JavaScript and XML)的無重新整理和非同步讀取機制對其進行最佳化。

本專案檔已經上傳,在文章結尾處,大家不要再公布自己的email了,注意隱私.

對於Ajax的介紹,國內外的技術網站都有不少的資料,我在此不多說了。我所使用的Ajax來自http://ajax.schwarz-interactive.de/,大家有興趣可以去下載。 

首先來看看做出來的效果: 


這是剛載入好頁面的效果。
這是剛剛點擊節點,展開的瞬間(不好抓取啊)。
非同步讀取完成後,名為11000000節點的變化。這是在非同步呼叫完成後,資料已經在Tree
View中產生。
當完全展開11000000下的一個子節點時,可以發現根節點如此之多。

這是我仿造項目做的一個解決方案:
其中BorgWorX.Web.Core.Ajax產生Ajax.DLL
第一步:按AjaxGuide.doc上說的來,先在web.config中進行修改,增加:

<add
verb="POST,GET" path="ajax/*.ashx"
type="BorgWorX.Web.Core.Ajax.PageHandlerFactory, BorgWorX.Web.Core.Ajax" />

第二步:我們在page load事件時向Ajax註冊頁面類,並向tree view控制項綁定UNSPSC第一層的資料: 

private void
Page_Load(object sender, System.EventArgs e)
{
BorgWorX.Web.Core.Ajax.Utility.RegisterTypeForAjax(typeof(WebForm2));
   
LoadNode=new TreeNode();
   
LoadNode.Text="Loading";
   
LoadNode.ID="load";

 
if(!IsPostBack)

{
       
TreeNode root=new TreeNode();
       
root.Text="Root";
       
TreeView1.Nodes.Add(root);
       
loadData(root,0); //Data Bind
       
root.Expanded=true;
   
}
}

第三步:在後台代碼中編寫要使用Ajax的方法,並對其添加中繼資料屬性。要注意的是這些方法必須聲明為public,在這兒我聲明一個名為returnDs的方法,它根據前置詞字元串返回資料庫中所有包含此首碼的記錄:

[BorgWorX.Web.Core.Ajax.AjaxMethod()]
public  DataSet
returnDs(string PreFix)
{

int preFix=getPreFix(PreFix);
string
str="workstation id=DINGSEA;packet size=4096;user id=sa;data
source=dingsea;persist security info=False;initial catalog=GEPS";
    DataSet
ds=SqlHelper.ExecuteDataset(str,"sp_loadUNSPSCCodeByLevel",preFix);

return ds;
}
private int
getPreFix(string code)
{

string tempStr;

while(code.EndsWith("00"))

{
       
code=code.Remove(code.Length-2,2);
   
}
   
tempStr=code;
return
tempStr.Length==0?0:Convert.ToInt32(tempStr);
}

這樣我們在用戶端寫JS的時候就可以方便的使用這個方法了。

第四步:服務端搞定後,我們來看看用戶端如何設計。通過page_load方法載入了第一層的UNSPSC
Code,也就是XX000000的所有節點並顯示出來。通過對TreeView WebControl的用戶端行為進行考察(微軟在其文章《About the
TreeView WebControl》中有提到),我們發現可以在TreeView的OnExpand事件中,進行非同步下載子層資料: 

<script language="javascript">

var Index;

function ds()

{

WebForm2.returnDs(TreeView1.getTreeNode(Index).getAttribute("NodeData"),returnDs_callback);

}

function returnDs_callback(response)

{

var n=TreeView1.getTreeNode(Index);

var load=n.getChildren();

if(load.length!=1){

return;//如果已經存在資料,那就不再讀取。

}

else

{

var loadNode=load[0];

loadNode.remove();

}

var ds=response.value;

if(ds!=null && ds.Tables!=null && typeof(ds)=="object")

{

for(var i=0;i<ds.Tables[0].Rows.length;i++)

{

var newNode=TreeView1.createTreeNode();

newNode.setAttribute("NodeData",ds.Tables[0].Rows[i].UNSPSCCode);

newNode.setAttribute("Text",ds.Tables[0].Rows[i].UNSPSCCode+"
"+ds.Tables[0].Rows[i].Description);

if(newNode.getAttribute("NodeData")%100==0)

{

var loadNode=TreeView1.createTreeNode();

loadNode.setAttribute("Text","Loading......");

newNode.add(loadNode);

}

n.add(newNode);

}

}

else{alert(response.error);}

}

</script>

<script language="javascript" for="TreeView1" event="onexpand">

//TODO:在此處填寫TreeView的OnExpand事件的代碼。

Index= window.event.treeNodeIndex;//獲得展開的節點的位置,根節點為0。

if(Index=='0')return;//如果是根節點的話就直接返回。

ds();

</script>

按這樣的情況來算,業務中每層節點最多99個,一共四層節點,也就是99*99*99*99=
9227446944279201(更正:96059601,自己汗一個先。)個節點。遠遠超過需求中的9000萬個,而且在使用者展開節點後先出現的是“Loading……”的字樣,同時在伺服器上去下載節點,不但最佳化了效能提高了效率而且還更人性化、介面更有親和力。

 /Files/wangyt223/project.rar

本專案檔已經上傳,在文章結尾處,大家不要再公布自己的email了,注意隱私.

對於Ajax的介紹,國內外的技術網站都有不少的資料,我在此不多說了。我所使用的Ajax來自http://ajax.schwarz-interactive.de/,大家有興趣可以去下載。 

首先來看看做出來的效果: 


這是剛載入好頁面的效果。
這是剛剛點擊節點,展開的瞬間(不好抓取啊)。
非同步讀取完成後,名為11000000節點的變化。這是在非同步呼叫完成後,資料已經在Tree
View中產生。
當完全展開11000000下的一個子節點時,可以發現根節點如此之多。

這是我仿造項目做的一個解決方案:
其中BorgWorX.Web.Core.Ajax產生Ajax.DLL
第一步:按AjaxGuide.doc上說的來,先在web.config中進行修改,增加:

<add
verb="POST,GET" path="ajax/*.ashx"
type="BorgWorX.Web.Core.Ajax.PageHandlerFactory, BorgWorX.Web.Core.Ajax" />

第二步:我們在page load事件時向Ajax註冊頁面類,並向tree view控制項綁定UNSPSC第一層的資料: 

private void
Page_Load(object sender, System.EventArgs e)
{
BorgWorX.Web.Core.Ajax.Utility.RegisterTypeForAjax(typeof(WebForm2));
   
LoadNode=new TreeNode();
   
LoadNode.Text="Loading";
   
LoadNode.ID="load";

 
if(!IsPostBack)

{
       
TreeNode root=new TreeNode();
       
root.Text="Root";
       
TreeView1.Nodes.Add(root);
       
loadData(root,0); //Data Bind
       
root.Expanded=true;
   
}
}

第三步:在後台代碼中編寫要使用Ajax的方法,並對其添加中繼資料屬性。要注意的是這些方法必須聲明為public,在這兒我聲明一個名為returnDs的方法,它根據前置詞字元串返回資料庫中所有包含此首碼的記錄:

[BorgWorX.Web.Core.Ajax.AjaxMethod()]
public  DataSet
returnDs(string PreFix)
{

int preFix=getPreFix(PreFix);
string
str="workstation id=DINGSEA;packet size=4096;user id=sa;data
source=dingsea;persist security info=False;initial catalog=GEPS";
    DataSet
ds=SqlHelper.ExecuteDataset(str,"sp_loadUNSPSCCodeByLevel",preFix);

return ds;
}
private int
getPreFix(string code)
{

string tempStr;

while(code.EndsWith("00"))

{
       
code=code.Remove(code.Length-2,2);
   
}
   
tempStr=code;
return
tempStr.Length==0?0:Convert.ToInt32(tempStr);
}

這樣我們在用戶端寫JS的時候就可以方便的使用這個方法了。

第四步:服務端搞定後,我們來看看用戶端如何設計。通過page_load方法載入了第一層的UNSPSC
Code,也就是XX000000的所有節點並顯示出來。通過對TreeView WebControl的用戶端行為進行考察(微軟在其文章《About the
TreeView WebControl》中有提到),我們發現可以在TreeView的OnExpand事件中,進行非同步下載子層資料: 

<script language="javascript">

var Index;

function ds()

{

WebForm2.returnDs(TreeView1.getTreeNode(Index).getAttribute("NodeData"),returnDs_callback);

}

function returnDs_callback(response)

{

var n=TreeView1.getTreeNode(Index);

var load=n.getChildren();

if(load.length!=1){

return;//如果已經存在資料,那就不再讀取。

}

else

{

var loadNode=load[0];

loadNode.remove();

}

var ds=response.value;

if(ds!=null && ds.Tables!=null && typeof(ds)=="object")

{

for(var i=0;i<ds.Tables[0].Rows.length;i++)

{

var newNode=TreeView1.createTreeNode();

newNode.setAttribute("NodeData",ds.Tables[0].Rows[i].UNSPSCCode);

newNode.setAttribute("Text",ds.Tables[0].Rows[i].UNSPSCCode+"
"+ds.Tables[0].Rows[i].Description);

if(newNode.getAttribute("NodeData")%100==0)

{

var loadNode=TreeView1.createTreeNode();

loadNode.setAttribute("Text","Loading......");

newNode.add(loadNode);

}

n.add(newNode);

}

}

else{alert(response.error);}

}

</script>

<script language="javascript" for="TreeView1" event="onexpand">

//TODO:在此處填寫TreeView的OnExpand事件的代碼。

Index= window.event.treeNodeIndex;//獲得展開的節點的位置,根節點為0。

if(Index=='0')return;//如果是根節點的話就直接返回。

ds();

</script>

按這樣的情況來算,業務中每層節點最多99個,一共四層節點,也就是99*99*99*99=
9227446944279201(更正:96059601,自己汗一個先。)個節點。遠遠超過需求中的9000萬個,而且在使用者展開節點後先出現的是“Loading……”的字樣,同時在伺服器上去下載節點,不但最佳化了效能提高了效率而且還更人性化、介面更有親和力。

 /Files/wangyt223/project.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.