首页 > 代码库 > 使用脚本操作UpdatePanel中控件的问题

使用脚本操作UpdatePanel中控件的问题

假设有一个脚本(用js或者jQuery等类似手段编写),为UpdatePanel中的一个普通的TextBox赋值。如果你以为这样写:

<head runat="server">
    <title>Test</title>
    <script src="http://www.mamicode.com/Scripts/jquery-2.0.0.js"></script>
    <script>
        $(function ()
        {
            $(‘#<%=TextBox1.ClientID%>‘).val("I‘m Bill Gates!");
        });
    </script>
</head>

  你将发现程序一开始运行还正常,但是如果在UpdatePanel中加上一个Button,点击里边的Button之后TextBox1将不再存有文字。

  为什么呢?因为UpdatePanel是一个异步的回发页面。这个页面在初次加载的时候自然随着整个页面的刷新加载而加载,因此作用于页面级别的jQuery代码可以起到作用。但是等到点击button之后,仅仅是UpdatePanel中的内部内容刷新了,整个页面根本不刷新(换句话说,整个页面的jQuery根本没有执行)。因此没有任何作用了。

  解决方案就是设法获取异步页面的加载脚本事件,然后进行赋值:

<head runat="server">
    <title>Test</title>
    <script src="http://www.mamicode.com/Scripts/jquery-2.0.0.js"></script>
    <script>
        $(function ()
        {
            $(‘#<%=TextBox1.ClientID%>‘).val("董玮……");
            var content = Sys.WebForms.PageRequestManager.add_beginrequest(function(){$(‘#<%=TextBox1.ClientID%>‘).val("董玮……");});
        });
    </script>
</head>

  注意:“$(‘#<%=TextBox1.ClientID%>‘).val("I‘m Bill Gates!");”这句话绝对不能省略,因为Sys.WebForms.PageRequestManager仅处理异步页面回发时候的情况。除此之外,另外微软还提供了一个Application类。

  其实这是微软已经封装的一个类,我们可以拿它和一般的服务端的Page类做一个类比,方便记忆(只不过一个处理服务端,一个是客户端而已):其中PageRequestManager位于Sys.WebForms下,必须通过getInstance方法获取单例之后使用,而Sys.Application可以直接使用。以下给出的是类比的一些“对等情况”:

        服务端类              客户端类

    Page类                  Application类  

            Page_Init                      add_init方法        

            Page_Load                   add_load方法

            Page_Unload              add_unload方法

  对比这些方法,你发现Page的Load事件和客户端的Application的Load事件一样重要:前者是加载了全部的服务端控件之后可以开始在此写代码进行对服务端控件进行服务端的操作。后者则从客户端的角度(加载了所有Html以及服务端自动生成的脚本等),可以进行额外的控制了。一般我们开发人员主要考虑在这两个事件中处理事情居多。同样地,这两个事件:

 【相同点】一旦页面刷新,或者点击Submit页面导致整个页面回发,或者位于UpdatePanel中的按钮导致局部页回发,Page_Load和add_load照样执行。

 【不同点】Page_Load可以通过if(!IsPostBack){……}的方式判断是否回发。add_load未提供了类似机制判断局部页面是否回发。但是PageRequestManager却提供了一个方法(get_isInAsyncPostBack())来判断是否是第一次页面异步回发。如果把脚本注册代码仅写在这个方法块里边,和Page_Load那种效果一样,只注册一次脚本。所以根据情况而定。

  至于PageRequestManager的事件是针对UpdatePanel为主。有InitRequesting,BeginRequest,pageloading,pageload和endRequesting等事件。我们做一个实验,看看执行顺序:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="VB.WebForm1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/jquery-2.0.0.js"></script>
    <script>
        $(document).ready(function () {
            Sys.Application.add_init(function () {
                alert("add_Init");
            });
            Sys.Application.add_load(function () {
                alert("add_Load");
            });
            var page = Sys.WebForms.PageRequestManager.getInstance();
            page.add_initializeRequest(function ()
            {
                alert("page_Init");
            });
            page.add_beginRequest(function () {
                alert("page_beginRequest");
            });
            page.add_pageLoading(function () {
                alert("page_Loading");
            });
            page.add_pageLoaded(function () {
                alert("page_Loaded");
            });
            page.add_endRequest(function ()
            {
                alert("page_endRequest");
            });
        });
    </script>
</head>
<body onload="Myfun">
    <form id="form1" runat="server">
        <div>

            <asp:ScriptManager ID="ScriptManager1" runat="server">
              
            </asp:ScriptManager>
           
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <div id="MyDiv"></div>
                    <asp:Button ID="Button1" runat="server" Text="Inner Button1" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
    </form>
</body>
</html>

  实验结果:

      页面刚加载的时候:先执行add_Init,然后page_loaded,最后add_Load。

  当点击Button的时候:1)page_Init 2)page_beginRequest 3)page_loading 4)page_loaded 5)add_load 6)page_endRequest。

  【结论】

  1、Application一般用于整个页面(凡是页面刷新或者回传,都会导致此事件发作)。Init只发生一次。load可以多次发生。

  2、PageRequestManager用于单个可以回发的控件(比如UpdatePanel)。初始化加载时候随着整个页面加载,因此page_loaded先加载完毕之后整个Application才加载完毕。单击Button的时候,就UpdatePanel回发,因此page方面的事件逐一被激发,最后重新加载UpdatePanel,然后Application的load事件才被激发(全部页面加载完毕)。

  有关于这些内容详细信息,可以参考MSDN:

  http://msdn.microsoft.com/zh-cn/library/bb398976(v=vs.100).aspx

  http://msdn.microsoft.com/zh-cn/library/bb310856(v=VS.100).aspx

 

原文:http://www.cnblogs.com/ServiceboyNew/archive/2013/05/04/3059014.html