Ajax.Net–PageRequestManager對象

來源:互聯網
上載者:User
 
ScriptManager和UpdatePanel兩個控制項已經能夠實現了用戶端與伺服器端的非同步通訊了。要想對非同步作業進一步控制的話,那我們還得進一步研究PageReqeustManager類。
PageRequestManager類是用戶端的類,用於協調ScriptManager和UpdatePanel控制項,管理頁面上的非同步更新操作。通過PageRequestManager用戶端的執行個體我們可以深入到在用戶端頁面生命週期中,更細緻地操作用戶端的頁面。
一、PageRequestManager執行個體:
    要想在用戶端獲得PageRequestManager執行個體,頁面上必須擁有一人ScriptManager控制項,並且ScriptManager控制項的EnablePartialRendering屬性必須設為True。
    只要頁面上內含一個EnablePartialRendering屬性為True的ScriptManager控制項,該頁面就會自動建立一個PageRequestManager執行個體。程式員不需要自行建立PageRequestManager執行個體,直接取來用即可。
    取得PageRequestManager執行個體的代碼:
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        屬性prm.get_isInAsyncPostBack():判斷一個非同步回送是否進行中中。
        方法prm.abortPostBack():把一個正在執行中的非同步回送取消。
二、用戶端頁面的生命週期:
    PageRequestManager類的優勢就是能夠讓程式員深入至用戶端頁面的生命週期中去。所以要想充分發揮PageRequestManager類的功能,那首先要瞭解非同步頁的生命週期。
    1、initializeRequest:
       觸發時機:當一個非同步請求的回送被初始化之前引發。
       添加事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(initFunc);
       移除事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().remove_initializeRequest(initFunc);
           initFunc是該頁面初始化之前要執行的用戶端方法。該方法的聲明為:
           function initFunc(sender,args)
           {
                //args的資料類型是:InitializeRequestEventArgs類型。
                //args.get_postBackElement():取得初始化非同步回送的元素對象。
                   //args.get_postBackElement().id取得初始化非同步回送的元素對象的id號
                   //args.get_postBackElement().value取得初始化非同步回送的元素對象的value值
                //args.set_cancel(bool):未初始化非同步回送,即丟棄該非同步回送。
           }
        如果非同步處理的過程比較慢,在非同步處理的過程中再次發出同樣的請求的話,那後者的非同步處理請求會取消掉前一步未處理完的請求。這就是預設的非同步請求優先順序--“後者優先”。
        我們通常回利用initailizeRequest事件來取消一個非同步回送(進行中的回送和將要初始化的回送)。          
    2、beginRequest:
       觸發時機:在非同步請求初始化完成,且向伺服器提出請求之前引發。
       添加事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginFunc);
       移除事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(beginFunc);
           beginFunc是向伺服器提出請求之前要執行的用戶端方法。該方法的聲明為:
           function beginFunc(sender,args)
           {
                //args的資料類型是:BeginRequestEventArgs類型。
                //args.get_postBackElement():取得初始化非同步回送的元素對象。
           }
        我們通常在beginRequest事件中設定一個標題,或是啟始化一個動化告知使用者進行中請求處理。
    3、pageLoading:
        觸發時機:非同步回送已經被伺服器接收並響應,但還沒有對頁面進行任何更新之前引發
        添加事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(loadingFunc);
        移除事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().remove_pageLoading(loadingFunc);
             loadingFunc是頁面更新之前要執行的用戶端方法。該方法的聲明為:
             function loadingFunc(sender,args)
             {
                //args的資料類型是:PageLoadingEventArgs類型。
                //args代表內容將要被更新或刪除的UpdatePanel控制項的<div>。
                //var arr = args.get_panelsDeleting(); 取得將被刪除的各個UpdatePanel控制項的<div>
                //var arr = args.get_panelsUpdating();取得將被更新的各個UpdatePanel控制項的<div>
             }
    4、pageLoaded:
        觸發時機:回送完成頁面地區被更新之後引發。
        添加事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(loadedFunc);
        移除事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(loadedFunc);
           loadedFunc是頁面更新後要執行的用戶端方法。該方法的聲明為:
           function loadedFunc(sender,args)
           {
                //args的資料類型是:PageLoadedEventArgs類型
                //args代表更新的或建立的UpdatePanel控制項的<div>
                //var arr = args.get_panelsUpdated();取得被更新的各個UpdatePanel控制項的<div>
                //var arr = args.get_panelsCreated();取得新建立的各個UpdatePanel控制項的<div>
           }
    5、endRequest:
       觸發時機:回送請求處理完畢後,就會引發endRequest事件。
       添加事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endFunc);
       移除事件處理代碼:Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(endFunc);
           endFunc是頁面請求完成後執行的用戶端方法。該方法的聲明為:
           function endRequest(sender,args)
           {
                //args的資料類型是:EndRequestEventArgs類型
                //var err = args.get_error():判斷是否發生錯誤,並取得錯誤對象。
                //var em = args.get_error().message:取得錯誤的出錯資訊。
                //args.set_errorHandled(true):設定錯誤已被處理。
                //var gm = args.get_errorHandled():判斷錯誤是否被處理。
                //非同步請求發生異常後,如果程式員不在用戶端捕獲處理的話,PageRequestManager對象會將其以對話方塊的形式彈出異常的資訊。如果程式員想自己編寫錯誤處理代碼,而不交由PageRequestManager對象處理的話。那程式員可以通過args.get_error().message屬性取得錯誤資訊,然後編寫異常處理代碼,最後記得執行args.set_errorHandled(true)。這樣就阻止異常繼續回返給PageRequestManager對象。具體使用在後面將詳細說明。
           }
三、案例:
    1、非同步回送的優先順序-後者的優先順序高於前者:
        如果處理非同步回送用的時間很長的話,那麼在處理第一個回送的過程中,用戶端又產生第二次非同步回送的話話,那後引發的回送回取消先引發的回送。
        頁面上有兩個非同步按鈕,產生非同步回送,為了拉長伺服器端處理回送的時間,我分別在兩個按鈕的伺服器click事件中使用線程休眠了10秒和5秒,然後再向lblInfo標籤中輸入處理結果。
        

        <asp:Button ID="btnLong" runat="server" Text="10秒後產生響應" OnClick="btnLong_Click" />
        <asp:Button ID="btnShort" runat="server" Text="5秒後產生響應" OnClick="btnShort_Click" />
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="lblInfo" runat="server" BackColor="#C0C0FF" Width="100%"></asp:Label>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="btnLong" EventName="Click" />
                <asp:AsyncPostBackTrigger ControlID="btnShort" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>
        為了讓大家看清楚後一步引發會取消掉前一步的引發,我在PageRequestManager對象中加入了beginRequest事件處理代碼,在發送請求前在頁面上顯示請求寄件者 。
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_beginRequest(beginR);
        function beginR(sender,args)
        {
            var d = $get("lblInfo");
            var t = args.get_postBackElement().value;
            d.innerHTML = "正在處理同"+t+"引發的回送";
        }
       伺服器端的代碼:
        protected void Page_Load(object sender, EventArgs e)
        {
            ScriptManager1.RegisterAsyncPostBackControl(this.btnLong);
            ScriptManager1.RegisterAsyncPostBackControl(this.btnShort);
        }
        protected void btnLong_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(10000);
            lblInfo.Text = ((Button)sender).Text + "產生的響應";
        }
        protected void btnShort_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(5000);
            lblInfo.Text = ((Button)sender).Text + "產生的響應";
        }
        效果:當點擊"10秒後產生響應"按鈕的時候,在lblInfo中會顯示"正在處理同10秒後產生響應引發的回送",如果此時你再點擊"5秒後產生響應"按鈕的時候,lblInfo的顯示會變成"正在處理同5秒後產生響應引發的回送"。此時第一次引發的回送回被取消,等待5後頁面上會顯示出"5秒後產生響應產生的響應",並不出現第一次回送的伺服器響應。
      
    2、取消非同步回送:       
        取消非同步回送分兩種:
            a. 取消自在執行的非同步回送-通過調用PageRequestManager對象的abortPostback()方法來取消。
            b. 取消新產生的異點回送-通過設定InitializeRequestEventArgs對象的cancel屬性為true來取消。
          
        下面是一個查詢汽車資訊的介面,為了拉長伺服器的處理時間,我在查詢按鈕中加入了6秒中的休眠時間。
        在點擊查詢的時候,為了不讓使用者乾等,我加入了一個<div>,提示使用者請求正在處理中,在<div>中加入一個"取消"按鈕,當使用者點擊 "取消"按鈕的時候,可以中止伺服器端的非同步處理。
        

        等到伺服器處理完畢非同步請求後顯示下面的介面
        

        如果在伺服器未處理完非同步請求時,使用者再點擊"查詢"按鈕,做到防止後引發的回送衝掉第一次引發的回送,並在介面中加入提示資訊。
        

        
        介面設計:
       

        HTML代碼如下:
       <asp:ScriptManager ID="ScriptManager1" runat="server" AsyncPostBackErrorMessage="這是一個自訂的小異常">
        </asp:ScriptManager>
        <asp:DropDownList ID="ddl" runat="server" DataSourceID="SqlDataSource1" DataTextField="prod_name"
            DataValueField="prod_code" Width="194px">
        </asp:DropDownList>
        <asp:Button ID="Button1" runat="server" Text="查詢" OnClick="Button1_Click" />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:mydbConnectionString %>"
            SelectCommand="SELECT [prod_code], [prod_name] FROM [productor]"></asp:SqlDataSource>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <div id="divInfo" style="background-color: #ff99ff; display: none;">
                    <asp:Button ID="btnCancel" runat="server" Text="取消" /></div>
                <br />
                <asp:GridView ID="list" runat="server" Width="100%" DataSourceID="SqlDataSource2">
                </asp:GridView>
                <asp:SqlDataSource ID="SqlDataSource2" runat="server" >
          
                </asp:SqlDataSource>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>
      
       CS代碼如下:
        protected void Page_Load(object sender, EventArgs e)
        {
            ScriptManager1.RegisterAsyncPostBackControl(this.Button1);
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(6000);
            string str = WebConfigurationManager.ConnectionStrings["mydbConnectionString"].ToString();
            SqlDataSource2.ConnectionString = str;
            SqlDataSource2.SelectCommand = "select car.ids,car.name,car.price,brand.brand_name,prod_code from car join brand on car.brand=brand_code where prod_code=@p";
            SqlDataSource2.SelectParameters.Clear();
            SqlDataSource2.SelectParameters.Add("p",ddl.SelectedValue);
            SqlDataSource2.Select(DataSourceSelectArguments.Empty);
        }
      
       用戶端JS代碼的實現:
        var prm = Sys.WebForms.PageRequestManager.getInstance();     //取得PageRequestManager對象的執行個體
        prm.add_initializeRequest(init);    //添加對象初始化事件處理常式
        function init(sender,args)   //事件處理常式
        {
            //如果在非同步處理過程中,點擊了"取消"按鈕的話,就中止正在處理的非同步處理 。
            if(prm.get_isInAsyncPostBack() && args.get_postBackElement().id=="btnCancel")
            {
                prm.abortPostBack(); //中止非同步處理
            }
           //如果在非同步處理過程中,又點擊了一次"查詢"按鈕的話,就取消新的請求。
            else if(prm.get_isInAsyncPostBack() && args.get_postBackElement().id=="Button1")
            {
                args.set_cancel(true);    //取消新的請求
                var d = $get("divInfo");
                d.style.display = "";
                d.innerHTML += "<br>仍然正在請求中,請稍候";
            }
           //如果沒有非同步處理正在執行,使用者點擊了"查詢"按鈕的話,就顯示"正在請求中,請稍候"
            else if(!prm.get_isInAsyncPostBack() && args.get_postBackElement().id=="Button1")
            {
                var d = $get("divInfo");
                d.style.display = "";
                d.innerHTML += "<br>正在請求中,請稍候";
            }
        }
      
    3、非同步請求自訂的錯誤處理。       
    在非同步請求處理中如果產生錯誤,系統預設會彈一個瀏覽的對話方塊,告訴使用者的出錯資訊。有時候我們並不想用這種預設的異常處理介面,那如何處理呢?
    實現步驟:
       a、編寫ScriptManager對象的伺服器端事件ScriptManager1_AsyncPostBackError代碼,把捕獲的錯誤資訊賦給ScriptManager對象的AsyncPostBackErrorMessage屬性。
       b、添加PageRequestManager對象的endRequest事件處理常式。在處理常式中用args.get_error().message取出運行中的錯誤資訊。然後在指定的<Div >中把錯誤資訊顯示出來。
       c、用set_errorHandled(true)把錯誤對象標記為已處理,防止錯誤對象繼續冒泡給瀏覽器。
    介面:
        

       
           

    HTML代碼:
        <asp:ScriptManager ID="ScriptManager1" runat="server" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError">
        </asp:ScriptManager>
        <br />
        <asp:Button ID="btnOK" runat="server" OnClick="btnOK_Click" Text="成功送出" />
        <asp:Button ID="btnError" runat="server" OnClick="btnError_Click" Text="送出失敗" /></div>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="lblInfo" runat="server" BackColor="#C0C0FF" Width="100%"></asp:Label>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="btnError" EventName="Click" />
                <asp:AsyncPostBackTrigger ControlID="btnOK" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>    
    CS代碼:
        protected void Page_Load(object sender, EventArgs e)
        {
            ScriptManager1.RegisterAsyncPostBackControl(btnOK);
            ScriptManager1.RegisterAsyncPostBackControl(btnError);
        }
        protected void btnOK_Click(object sender, EventArgs e)
        {
            lblInfo.Text = "非同步回送成功";
        }
        protected void btnError_Click(object sender, EventArgs e)
        {
            Exception ex = new Exception("這是一個自訂的使用者異常資訊");
            throw ex;
        }
        protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
        {
            ScriptManager1.AsyncPostBackErrorMessage += e.Exception.Message;
        }             
    用戶端JS代碼:
       var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_endRequest(endfunc);
        function endfunc(sender,args)
        {
            if(args.get_error() != null)
            {
                var em = args.get_error().message;
                args.set_errorHandled(true);
                $get("lblInfo").innerHTML = em;
            }
        }  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.