代码改变世界

讲座展示:TechEd Europe DEV 411 - AJAX Patterns with ASP.NET AJAX(2)

2006-12-08 15:33 Jeffrey Zhao 阅读(...) 评论(...) 编辑 收藏

这次我选择的讲座内容,是最近在TechEd 2006 Europe中Andre Snanbria和Jeff Prosise的讲座“AJAX Pattern with ASP.NET AJAX”。Jeff Prosise是Wintellect的Co-Founder,Andre Sanabria是ASP.NET AJAX Team的Lead Program Manager。在MSDN's Showtime上已经有了这个讲座的完整视频,而我在早些时候给Andre Sanabria写了封Email,一星期后他给我寄来了这个讲座的PPT和Demo,大家可以点击这里下载。

这次讲座的主要内容是讲述了使用ASP.NET AJAX开发AJAX应用的最佳实践,在这次讲座里,会对建立轻量级的客户端控件的方法进行深入,讲述了如何优化脚本代码,并提出了如何避免AJAX开发中常见的问题。

本篇文章是这次讲座展示的第二篇,讲述了UpdatePanel的工作方式。

讲座内容

Jeff:很好,有很多最佳实践和合适的编程模式来简化编写AJAX应用的方式。就像Andre说的,我们现在要做的就是回头向大家一点点地展示一些我们已经实现的代码。可能它们和其它我们在这周展示给大家的有关ASP.NET AJAX的东西会有些不同,不过所有的我们做的,我们实现这些应用的方式,目的都是尽可能的做到更高的效率。

Jeff:那么我们现在就来考虑对于这个应用程序的进行增强的第一步,我们第一步想看的东西。我们在这个应用中使用了“局部刷新”的技术,事实上在刚才的照片浏览页面,用到的并不是1个,而是4个不同的UpdatePanel。你们可能已经很清楚了,UpdatePanel完全就是用来“局部刷新”的。用户对于页面的PostBack和它造成的页面闪烁以及视觉中心的丢失,都可以说是深恶痛绝。当我们现在谈论到AJAX最先想到的就是“局部刷新”,就是不进行PostBack,而是对服务器端进行轻量级的异步CallBack。带来这些美妙东西的就是XMLHttpRequest,它能使浏览器不将现有的HTML给丢弃,因此我们就避免了页面的闪烁。如果您自己写AJAX代码的话,是需要比较多的工作才能完成的。UpdatePanel的美妙之处就在于,我能够简单地将它拖动到页面上,在它内部放置一些我们需要局部刷新的元素,然后UpdatePanel就会为我们管理那些元素的各种复杂情况了,这实在是一种魔法——直到您了解了让它能够这样的工作是多么地不容易。不过这是一种交易。如果我简单地在页面上放置几个UpdatePanel,我可能无法得到我期望的结果——的确,它增强了用户体验,但是在另一方面,它也让一些不需要的数据在客户端和服务器端之间来回。不仅仅是在一个单独的请求中发送了过多的数据,也有可能超出获得我们期望的多余的数据。

Jeff:在演示下一个Demo之前,我再多谈论一下UpdatePanel是如何工作的。当你把一个UpdatePanel放在页面中之后,在页面就会实例化一个类型为PageRequestManager的客户端对象。当然这些都由ScriptManager来完成这些工作了,当你把ScriptManager的EnablePartialRendering属性设为True之后,一个用于初始化PageRequestManager对象的脚本就被发送到客户端。我们把Microsoft AJAX在客户端的那部分称之为Microsoft AJAX Library。事实上,一个理解ScriptManager的好方法是从客户端的角度来看UpdatePanel。PageRequestManager做的事情就是异步地将数据传输到客户端,管理客户端与服务器端的数据交换,得到服务器端UpdatePanel输出的内容,通过改变浏览器DOM的方式将这些内容放置在客户端中。

Jeff:一般来说,如果一个没有UpdatePanel的页面,当我点击了页面上的一个“提交”按钮,页面被整个提交到了服务器端,在ASP.NET中我们称之为PostBack,因为数据通过了Post的方式传递“回(Back)”服务器端。不过因为有了PageRequestManager的神奇作用,这里就不会产生一个PostBack了。这时候数据就是用了XMLHttpRequest被异步地发送到了服务器端,在服务器端会产生一个round-trip,但是现在我们就不会让浏览器放弃它已经拥有的HTML了。让我来告诉您一些UpdatePanel更详细的一些秘密。大部分的人都会认为UpdatePanel会带来很高的效率——直到我们查看了客户端和服务器端交互的数据。一个传统的PostBack会将客户端所有的ViewState传递到服务器端,当然也包括所有页面上需要向服务器端Post的数据。事实上UpdatePanel的一个秘密就是:它也作了相同的事情。您可能会认为UpdatePanel并不会将ViewState以及多余的数据传回客户端,不过它的确这么做了。在这方面,一个UpdatePanel和一个传统的PostBack并没有什么区别,因此UpdatePanel并不是一种依靠避免传递ViewState而得到更高性能的方法。UpdatePanel这么做有个很重要的原因:因为在UpdatePane发送一个异步的CallBack时,您在服务器端也需要访问平时一直用到的ASP.NET的对象模型,这也意味着当一个异步的CallBack将数据发送到服务器端时,所有的控件树都会被重建,会经历一个传统的生命周期,这一切和传统PostBack的结果几乎完全相同:控件树会被重建,然后触发事件。事实上,在控件的事件被触发时有一点不同,这时候ASP.NET会意识到:“嘿,这不是个传统的PostBack,这是个页面的PageRequestManager发送的异步CallBack。”然后ASP.NET会让这个页面请求继续被处理,和传统PostBack相比,在服务期端处理时有很大区别的一点就是生命周期里的“Render”部分。传统状况下,页面会生成所有的内容,从控件树的最顶端直到控件树的最后。而UpdatePanel在这里的美妙之处就在于,它只会让UpdatePanel内部的控件被生成,在这里我们的确节省了一些消耗,因为我们在服务器端执行了较少的代码。不过这点性能的提高,可能完全被之前的消耗所抵消了,我们还是进行了一个完整的PostBack。这里我们可以是用一些方法,让我们能够尽可能高效地使用UpdatePanel。这幅图(上图)的最后,就表示了,当UpdatePanel在生成它内部控件的HTML之后将其发送到了客户端,而PageRequestManager则会处理页面内容更新的方式。在默认情况下,UpdatePanel会生成一个DIV标签,您能够将其设置为SPAN标签。PageRequestManager会设置标签的innerHTML属性,用新的内容替换了旧的内容。

Jeff:下面让我们再体验一下刚才的照片浏览器,让我们更清楚地了解它是如何使用UpdatePanel,我们是如何将尽可能高效地使用UpdatePanel。

(未完待续)