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

来源:互联网 发布:服务的端口号为 编辑:程序博客网 时间:2024/06/04 19:18

======================================================
注:本文源代码点此下载
======================================================

这次我选择的讲座内容,是最近在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的工作方式,并通过几个步骤对这个例子进行优化。

讲座内容

andre:我先从展示没有updatepanel时的体验开始(~/optimization/0.simpleform.aspx)。这是个简单的页面(上图左,请注意back按钮无法使用),我们有几个相册供用户选择,然后我们将为它们添加tag。现在我们没有使用updatepanel,当选择了某一项时,您会发现发生了一个完整的页面刷新(上图中,我把back按钮可以使用了)。因为现在在我的本地机器上演示,因此这个刷新非常迅速。但是在互联网上就不会像本地那么快了,带宽会非常小。您可以发现,当我点击页面上每个单选按钮后,页面都会有完整的刷新(上图右,back按钮的列表多了几项)。

andre:我们现在来看一下该如何解决这个问题。我们解决这个问题的方法只是将updatepanel添加到页面上。正如jeff刚才提到的那样,我们在刚才的应用里使用了许多updatepanel。现在这个也是展示updatepanel的不错的例子(~/optimization/1.partialrendering.aspx)。

andre:我们首先先使用updatepanel包含一个服务器端的控件“panel”(如下):

asp:updatepanel runat="server" id="contentupdatepanel">

contenttemplate>

asp:panel runat="server" id="contentpanel" style="padding: 10px" />

contenttemplate>

triggers>

asp:asyncpostbacktrigger controlid="albumlist" />

triggers>

asp:updatepanel>

andre:然后我们使用updatepanel将一些checkbox控件包含起来,我们那些tag都是checkbox(如下):

asp:updatepanel runat="server" id="tagslistupdatepanel">

contenttemplate>

asp:checkboxlist runat="server" id="tagslist"

autopostback="true" enabled="false"

repeatcolumns="3"

onselectedindexchanged="ontagsselectedindexchanged">

asp:listitem>natureasp:listitem>

asp:listitem>landscapesasp:listitem>

asp:listitem>cityscapesasp:listitem>

asp:listitem>conference tripsasp:listitem>

asp:listitem>microsoftasp:listitem>

asp:checkboxlist>

contenttemplate>

asp:updatepanel>

andre:我们这里还有一个updatepanel(如下):

asp:updatepanel runat="server" id="tagsupdatepanel">

contenttemplate>

asp:label runat="server" id="tagslabel" />

contenttemplate>

asp:updatepanel>

andre:我们先来看一下现在的用户体验(老赵:这里就省略了),再来观察数据在客户端和服务器端之间是如何交换的。

andre:我们先打开一个工具——web development helper,然后打开logging开关。当我们点击某个tagging时,这个小工具记录了从我的浏览器发出的request和server回复的内容(上图左)。因此我们就可以清楚地看到当我们选中一个checkbox时,一个新的request就发送到服务器端了。那么我们现在就来仔细看一下到底在这里发生了什么(上图中)。

andre:首先,一个请求放送到当前的页面。然后我们可以发现一个新的header被添加到了请求中,它的名称是“x-microsoftajax”,值为“delta=true”。这表示客户端告诉服务器端,现在的是一个异步的请求,需要对页面上的部分内容进行刷新。如果看一下部分刷新的实现的话,可以发现我们会查找header,如果有上面的信息,则表示我们必须进行特别的步骤了,就是jeff刚才提到的那些步骤。当然,这只是第一步。

andre:第二步我想展示给大家看的则是到底发送了那些内容。大部分人没有意识到的是,当updatepanel在工作时,整张页面被发送到了服务器端。就像jeff说过,我们会将我们需要的所有信息,例如viewstate发送到服务器端。我们来看一下发送的内容(上图右)。发送了scriptmanager,viewstate内容等等,这是所有被发送到服务器端的内容。

andre:现在还有一个问题,服务器端到底返回了什么。我们可以从“response content”看到(上图)。这里有updatepanel的id,我们也可以猜到,它返回了updatepanel里所有的html内容,在这里是个div,这就是我们会用来替换的内容。然后还有第二个updatepanel和第三个updatepanel。然后我们会将所有的viewstate发送到客户端。就像jeff说过的,我们需要在roundtrip时需要包含viewstate的原因是为了传输我们在客户端作了什么改变,在服务器端又作了什么改变。我们需要使用最新的数据来重建整个控件树,这就是我们需要viewstate数据的原因。

andre:下面就是jeff提到过的一个最佳实践。我打开这个工具的目的是要让大家知道,每次我们点击checkbox的时候发生了什么(上图)。每次我们点击checkbox时,我们就会去服务器端请求数据,然后将页面进行刷新。我们该如何解决这个问题?这个问题其实有个比较容易的解决方法。(andre不小心关闭了visual studio)呃……这个解决方案并不是关闭visual studio,我们再来重新看一下(~/optimization/2.optimizefrequency.aspx),我们在这里把checkboxlist的autopostback属性设为false(如下):

asp:checkboxlist runat="server" id="tagslist"

autopostback="false" enabled="false"

repeatcolumns="3">

asp:listitem>natureasp:listitem>

asp:listitem>landscapesasp:listitem>

asp:listitem>cityscapesasp:listitem>

asp:listitem>conference tripsasp:listitem>

asp:listitem>microsoftasp:listitem>

asp:checkboxlist>

andre:这里的想法就是,我们不让每次checkbox被选中或取消时就发送一次请求,我们只在我们准备好的情况下发送数据。我们再看一下页面(老赵:这里的截图就省略了),当我们选中一个像册时会发送一个请求。每次但我们点击checkbox时,我们不会给服务器端发送数据。不过当我们点击update按钮时,一个请求就出现了。这里的关键就在于,即使我们能够很快地与服务器端交互,我们也要仔细考虑一下,我们是否真的必要把autoposkback打开,让控件自动地与服务器端交互,因为这意味着页面上所有的数据将向服务器端进行一个来回。

andre:这里还有一些比较有趣的事情,我想展示一下刚才发生了什么。我们依旧回到刚才的“response content”,这就是从服务器端发回的内容,但是我们在这里使用“partial rendering”视图(上图)。这里发生的事情是,有个updatepanel被更新了,在每次请求之后,我们会更新所有的3个updatepanel,我们在这里使用updatepanel的默认设置,updatemode为always。这样,无论向服务器端请求的内容是什么,所有的updatepanel都会同时进行刷新。这里的问题就在于,我们可能不需要重新生成所有的updatepanel,我们需要的是简单地选择几个需要更新的updatepanel。这里就使用到updatepanel的一个属性,就是“conditional rendering”——噢,对不起,是“updatemode”。让我来告诉您我到底在说什么(~/optimization/3.optimizebandwidth.aspx)。

andre:在这里我将updatepanel的updatemode属性设为了“conditional”(老赵:这部分代码就不粘贴了)。现在的状况就变成了,updatepanel不必在每次请求时都进行更新,而是只有在特定情况下才重新生成它的内容。这些情况可能是我们通过updatepanel内部的控件进行了更新或者调用updatepanel的update方法。第二种情况则是通过了updatepanel的trigger,当一个控件被作为updatepanel的trigger时,则表示当这个控件发起postback之后,updatepanel将被更新。

andre:我们再来看一下,当我们点击update按钮之后,可以发现reponse的内容变得多小(上图左),当我们查看更新的updatepanel时,可以发现现在只有一个updatepanel被更新了(上图右)!从我们的最佳实践方面来说,我们不仅从数据传输着手,也考虑到了页面加载方面的问题。我们在这里将updatepanel的默认设置改成了条件生成(conditional rendering)。

(未完待续)


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/