• (转)用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……”的字样,同时在服务器上去下载节点,不但优化了性能提高了效率而且还更人性化、界面更有亲和力。

     /Files/wangyt223/project.rar

  • 相关阅读:
    深入浅出RxJava
    android 图像处理系列合集
    WebView·开发指南
    LocalBroadcastManager 的实现原理,Handler还是 Binder?
    TCP协议中的三次握手和四次挥手(图解)
    Android进程保活
    Android只能动态注册的广播Action
    WakeLock, AlarmManager, JobScheduler
    jQuery验证控件jquery.validate.js使用说明+中文API
    IntelliJ IDEA的自动提示貌似是区分大小写的,首字母小写的话,怎么都提示不出来。
  • 原文地址:https://www.cnblogs.com/wangyt223/p/2654695.html
Copyright © 2020-2023  润新知