极地银狐.NET

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  145 随笔 :: 11 文章 :: 1256 评论 :: 10 引用
相信不少人都用过微软提供的一款控件: IEControl, 其中的TreeView使用比较广泛。在我参与的一个项目中,一个名为UNSPSC的模块将频繁使用这个控件。这个控件在一般情况下相当好用(节点小于200个),但当节点数比较多时将使客户端长时间等待,大数据量时会让客户端超时以至于读取失败。本模块在进行压力测试时,数据库中有24000多条记录,一次性读取出来将使IE死掉,这自然不能适用于对UNSPSC的读取(UNSPSC要求最多支持9000万条记录)。于是我想使用AjaxAsynchronous 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》中有提到),我们发现可以在TreeViewOnExpand事件中,进行异步下载子层数据: 

<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:在此处填写TreeViewOnExpand事件的代码。

                 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

undefined undefined
posted on 2005-10-26 09:38 极地银狐.NET 阅读(9295) 评论(132)  编辑 收藏 网摘 所属分类: 开发人生代码天下

评论

楼主做的不错,但是算术估计没学好,99*99*99*99再怎么也小于100*100*100*100=100000000也就是一亿吧??怎么会算出来是9227446944279201呢
  回复  引用    

#2楼  2005-10-26 13:43 坐看风云起      
99*99*99*99= 9227446944279201 汗
  回复  引用  查看    

#3楼  2005-10-26 15:43 Boler Guo      
9227446944279201 = 99*99*99*99 * 99*99*99*99
  回复  引用  查看    

#4楼 [楼主] 2005-10-26 15:57 极地银狐.NET      
楼上各位不好意思,计算器多按了几下,给了一个错误的结果,在此致谢!
  回复  引用  查看    

#5楼  2005-10-27 17:08 ww [未注册用户]
老大!我试了一下,怎么返回大数据量不行呢,感觉都是用的Get,不是POST,怎么设置啊,我的<Form>可设置的都是POST
  回复  引用    

#6楼 [楼主] 2005-10-27 17:22 极地银狐.NET      
楼上的,应该是可行的,我机器上有现成的例子。主要是看你返回的数据量有多大了,如果太大,估计异步调用也搞不定。
  回复  引用  查看    

#7楼  2005-10-30 20:43 chinacs [未注册用户]
请问能打包下载吗,我按照上面的代码写了就是不能加载
  回复  引用    

#8楼  2005-11-01 12:42 雪石 [未注册用户]
楼主,你的方法非常不错,可是我试了一下没有成功,能够将Demo发到我的邮箱中吗?sx_duan@126.com谢谢了!
  回复  引用    

#9楼  2005-11-07 15:09 v_tron [未注册用户]
不好意思楼主,我试了下没有成功,能把你的demo代码发给我吗,我的邮箱:v_tron@hotmail.com,谢谢。
  回复  引用    

#10楼 [楼主] 2005-11-08 11:17 极地银狐.NET      
信已发送。
  回复  引用  查看    

#11楼  2005-11-08 17:23 福星人      
有空也发我一份philips_slg@163.com
  回复  引用  查看    

#12楼  2005-11-09 11:06 福星人      
在js中tree 的 onexpand事件好像不会激发
  回复  引用  查看    

#13楼  2005-11-09 18:25 雪石      
你发的邮件我已经收到,非常感谢!
  回复  引用  查看    

Would you send me a copy of the source codes? Thanks.

JoeTest123@hotmail.com
  回复  引用    

#15楼  2005-11-15 17:25 勋 [未注册用户]
很好,我可能会用到,能发到我油箱吗?maiweifen@126.com..
感谢!!!!
  回复  引用    

#16楼  2005-11-24 20:11 小飞 [未注册用户]
linjianghui@msn.com
  回复  引用    

#17楼  2006-01-23 16:58 kidfang [未注册用户]
拜托麻烦您发我一份,我苦苦寻找不到这样的代码
kidfang@xinhuanet.com
  回复  引用    

#18楼  2006-02-20 09:23 oo [未注册用户]
托麻烦您发我一份 : odz521@gmail.com
  回复  引用    

#19楼  2006-02-20 10:15 aysun168 [未注册用户]
谢谢,能不能发我一份:aysun168@163.com

  回复  引用    

#20楼 [楼主] 2006-02-20 10:18 极地银狐.NET      
以上两位,信已发送。
  回复  引用  查看    

#21楼 [楼主] 2006-02-20 10:24 极地银狐.NET      
@aysun168 :
信已发送。
  回复  引用  查看    

#22楼  2006-02-20 11:01 bukeqi [未注册用户]
linguangqu@msn.com
谢先!
  回复  引用    

#23楼  2006-02-20 11:01 bukeqi [未注册用户]
linguangqu@msn.com
谢先!
  回复  引用    

#24楼  2006-02-20 11:01 bukeqi [未注册用户]
linguangqu@msn.com
谢先!
  回复  引用    

#25楼 [楼主] 2006-02-20 12:17 极地银狐.NET      
信已发送
  回复  引用  查看    

#26楼  2006-02-20 17:32 路露 [未注册用户]
luxc@hstc.edu.cn,谢!
  回复  引用    

#27楼 [楼主] 2006-02-20 20:40 极地银狐.NET      
信已发送
  回复  引用  查看    

谢谢作者好文!期待您在百忙之中发一份源码
jinglin_t@163.com
感激ing....
  回复  引用    

#29楼 [楼主] 2006-02-21 12:47 极地银狐.NET      
信已发送
  回复  引用  查看    

#30楼  2006-02-22 09:06 babys [未注册用户]
多谢作者好文,attend1985@163.com 有空发一份给我啊,
  回复  引用    

#31楼  2006-02-22 09:26 小熊 [未注册用户]
kangpangpang@gmail.com谢谢阿
  回复  引用    

#32楼 [楼主] 2006-02-22 09:28 极地银狐.NET      
信已发送。
  回复  引用  查看    

#33楼  2006-02-22 13:47 Q_Q [未注册用户]
请给我一份.谢谢
ylwlf@163.com
  回复  引用    

#34楼 [楼主] 2006-02-22 21:23 极地银狐.NET      
信已发送
  回复  引用  查看    

非常感谢,我已收到邮件。
  回复  引用    

#36楼  2006-02-27 15:23 jecison [未注册用户]
谢谢.请楼主发一份源码.
jecison@cqyz.cn

万分感谢!!!!!!
  回复  引用    

#37楼 [楼主] 2006-02-27 22:06 极地银狐.NET      
信已发送.
  回复  引用  查看    

#38楼  2006-02-28 10:48 cloudsea [未注册用户]
谢谢.请楼主发一份源码.
cloudsea2001@sohu.com

十分感谢!
  回复  引用    

#39楼 [楼主] 2006-02-28 12:53 极地银狐.NET      
信已发送
  回复  引用  查看    

#40楼  2006-02-28 13:26 没剑 [未注册用户]
太好了,楼主发一份给偶吧
xiaolong300@21cn.com
  回复  引用    

尊敬的楼主:我用这个控件时就是刷新太明显,您可以发份代码给我吗?在此致谢
yanruolei@126.com
  回复  引用    

#42楼 [楼主] 2006-02-28 21:03 极地银狐.NET      
信已发送
  回复  引用  查看    

#43楼  2006-03-01 08:30 calmzeal      
楼主
我也想看看源码
calmzeal@163.com
谢谢
  回复  引用  查看    

楼主
也给我发一份吧,谢谢了
maxinlu2002@163.com
  回复  引用    

#45楼 [楼主] 2006-03-01 09:17 极地银狐.NET      
楼上两位,信已发送.
  回复  引用  查看    

您说的无刷新是不是不向服务器postback呢?
  回复  引用    

谢谢楼主,资料已经收到!
  回复  引用    

楼主给我一份#######################################################楼主给我一份
楼主给我一份
####楼主给我一份
#####楼主给我一份
#######楼主给我一份
xiexie ophxh@126.com
  回复  引用    

谢谢,已收到了
配置错误
说明: 在处理向该请求提供服务所需的配置文件时出错。请检查下面的特定错误详细信息并适当地修改配置文件。

分析器错误信息: Could not load type ajaxTest.defaultFilter from assembly atreetest.

源错误:


行 14: </httpHandlers>
行 15: <httpModules>
行 16: <add name="dingsea" type="ajaxTest.defaultFilter,atreetest"/>
行 17: </httpModules>
行 18: <!-- 动态调试编译

这是怎么会事啊?
  回复  引用    

#50楼 [楼主] 2006-03-01 17:57 极地银狐.NET      
@xinlusoaring:
是否postback请参考我写的Ajax源码分析.

@ophxh AT 126.com:信已发送

@xinlusoaring:好象是用来做httpModules留下的,我忘了删除,不好意思.
  回复  引用  查看    

slex999@163.com

也请楼主发一份!!
  回复  引用    

#52楼 [楼主] 2006-03-02 12:20 极地银狐.NET      
信已发送
  回复  引用  查看    

doohanwei@gmail.com
谢谢楼主
  回复  引用    

#54楼 [楼主] 2006-03-02 17:35 极地银狐.NET      
信已发送
  回复  引用  查看    

#55楼  2006-03-02 21:34 niss [未注册用户]
xianglii2000@163.com
谢谢楼主
  回复  引用    

#56楼 [楼主] 2006-03-03 22:04 极地银狐.NET      
信已发送
  回复  引用  查看    

#57楼  2006-03-04 21:36 Sunny Lau [未注册用户]
麻烦您发我一份 : sunny@goodwellchina.net
  回复  引用    

sunsky29@163.com
谢谢!

另外,有一个关于数的问题请教一下:
在有的IE中怎么无法获得节点的TEXT值,总返回NULL?
MTree.getTreeNode(MTree.clickedNodeIndex).getAttribute("Text")
  回复  引用    

#59楼  2006-03-05 19:00 Allen      
我也想看看。谢谢。
allen.lz.cn@gmail.com
  回复  引用  查看    

#60楼 [楼主] 2006-03-06 09:19 极地银狐.NET      
三位,信已发送。

@我也需要一份学习学习:在低IE版本中不支持树。具体树的用法请到MSDN看看,有一篇文章是讲Tree View client behavior的
  回复  引用  查看    

#61楼  2006-03-08 18:26 钱嘉奕 [未注册用户]
做的不错。
能给我一份学习一下吗?感谢、感谢!
我的邮箱 odear@126.com
  回复  引用    

Would you send me a copy of the DEMO source codes? Thanks.

piedmontlong@yahoo.com
  回复  引用    

#63楼 [楼主] 2006-03-10 10:10 极地银狐.NET      
楼上二位,信已发送
  回复  引用  查看    

樓主,我也要一份源碼,謝謝了。
guoqiandong@gmail.com
  回复  引用    

#65楼 [楼主] 2006-03-12 14:41 极地银狐.NET      
信已发送
  回复  引用  查看    

#66楼  2006-03-13 10:48 沙沙 [未注册用户]
谢谢.请楼主发一份源码.
egn_sha007@163.com

十分感谢!
  回复  引用    

#67楼 [楼主] 2006-03-14 09:55 极地银狐.NET      
信已发送
  回复  引用  查看    

#68楼  2006-03-16 11:17 SkySea [未注册用户]
谢谢.请楼主发一份源码.
skysea_feng@163.com
非常感谢!!!
  回复  引用    

#69楼  2006-03-17 20:04 wds [未注册用户]
我现在也遇到这个问题了,希望楼主施与帮助
wangds@royasoft.com.cn

多谢!
  回复  引用    

#70楼 [楼主] 2006-03-20 23:26 极地银狐.NET      
信已发送
  回复  引用  查看    

最近刚好要用到这方面的东东,向楼主化缘:)
liteng.net@gmail.com
  回复  引用    

#72楼  2006-03-22 08:29 默石 [未注册用户]
来晚了,我想要一份demo代码
我的邮箱hgaojixiang@gmail.com
谢谢啦
  回复