PageRequestManager對象(AjaxControlToolKit 客戶端事件)

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(function(){
    alert("在開始處理異步請求之前引發。可以使用此事件取消回發");
});
prm.add_beginRequest(function(){
    alert("在開始處理異步回發、將回發發送到服務器之前引發。可以使用此事件來設置請求標頭,或開始一個動畫以指示正在處理頁面");
});
prm.add_pageLoading(function(){
    alert("在收到服務器對異步回發的響應之後、頁上任何內容更新之前引發。可以使用此事件爲更新的內容提供自定義轉換效果");
});
prm.add_pageLoaded(function(){
    alert("在因同步回發或異步回發而刷新頁上的所有內容之後引發。可以使用此事件爲更新的內容提供自定義轉換效果");
});
prm.add_endRequest(function(){
    alert("在異步回發完成,並且控制權返回到瀏覽器之後引發。可以使用此事件向用戶提供通知或將錯誤記錄到日誌");
});
*********************************************************************************************************************

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標籤中輸入處理結果。
        

61f31c4eeb4afe05b3de05a2.jpg


        <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>中加入一個"取消"按鈕,當用戶點擊 "取消"按鈕的時候,可以中止服務器端的異步處理。
        

de77bd03929c8fe008fa93a3.jpg


        等到服務器處理完畢異步請求後顯示下面的界面
        

6a2f9e3f22878bce7d1e71a3.jpg


        如果在服務器未處理完異步請求時,用戶再點擊"查詢"按鈕,做到防止後引發的回送沖掉第一次引發的回送,並在界面中加入提示信息。
        

e71283ea38da19dfd539c9ac.jpg


        
        界面設計:
       

13643331c5419c15ebc4afad.jpg


        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)把錯誤對象標記爲已處理,防止錯誤對象繼續冒泡給瀏覽器。
    界面:
        

6daef9dee097fe54ccbf1aad.jpg

       
           

4aa4398d7562161eb31bbaae.jpg


    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;
            }
        }
           

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章