用Ajax技术让IE Web Control Tree View实现大数据量读取 【原文】

 
相信不少人都用过微软提供的一款控件: 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…… ”的字样,同时在服务器上去下载节点,不但优化了性能提高了效率而且还更人性化、界面更有亲和力。
 2006年4月5日修改:上传项目文件。 http://dingsea.cnblogs.com/Files/dingsea/Ajax/project.rar
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值