共用方式為


取消非同步回傳

更新:2007 年 11 月

非同步回傳是利用頁面上的 NET UpdatePanel Web 伺服器控制項,在 ASP.NET 中實作。有了 UpdatePanel控制項,每次回傳時就不必重新整理整個頁面,讓使用者更滿意。非同步回傳時,在瀏覽器中是由 Microsoft AJAX Library 中的 Sys.WebForms.PageRequestManager 類別來管理用戶端頁面生命週期中的事件。您可以處理 PageRequestManager 類別公開的事件,以自訂非同步回傳要如何發生。

本教學課程中,您將用 PageRequestManager 類別的 initializeRequest 事件來取消目前正在執行的非同步回傳。

如需 PageRequestManager 類別中引發之事件順序的詳細資訊,請參閱使用 PageRequestManager 事件

必要條件

若要在自己的開發環境中實作這些程序,您需要:

  • Microsoft Visual Studio 2005 或 Microsoft Visual Web Developer Express 版。

  • 具備 AJAX 能力的 ASP.NET 網站。

建立指令碼來取消回傳

首先,您必須建立 ECMAScript (JavaScript) 程式碼,來管理瀏覽器中的非同步回傳。

建立 JavaScript 程式碼來取消回傳

  1. 在 ASP.NET 網站中,加入新的 JScript 檔案,命名為 CancelPostback.js。

  2. 將下列指令碼加入至檔案:

    var divElem = 'AlertDiv';
    var messageElem = 'AlertMessage';
    
    Sys.Application.add_load(ApplicationLoadHandler)
    function ApplicationLoadHandler(sender, args)
    {
         Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus);
    }
    function CheckStatus(sender, args)
    {
      var prm = Sys.WebForms.PageRequestManager.getInstance();
      if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') {
         prm.abortPostBack();
      }
      else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
         args.set_cancel(true);
         ActivateAlertDiv('visible', 'Still working on previous request.');
     }
      else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
         ActivateAlertDiv('visible', 'Retrieving headlines.');
      }
    }
    function ActivateAlertDiv(visString, msg)
    {
         var adiv = $get(divElem);
         var aspan = $get(messageElem);
         adiv.style.visibility = visString;
         aspan.innerHTML = msg;
    }
    if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
    
    var divElem = 'AlertDiv';
    var messageElem = 'AlertMessage';
    
    Sys.Application.add_load(ApplicationLoadHandler)
    function ApplicationLoadHandler(sender, args)
    {
         Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus);
    }
    function CheckStatus(sender, args)
    {
      var prm = Sys.WebForms.PageRequestManager.getInstance();
      if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh') {
         prm.abortPostBack();
      }
      else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
         args.set_cancel(true);
         ActivateAlertDiv('visible', 'Still working on previous request.');
     }
      else if (!prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
         ActivateAlertDiv('visible', 'Retrieving headlines.');
      }
    }
    function ActivateAlertDiv(visString, msg)
    {
         var adiv = $get(divElem);
         var aspan = $get(messageElem);
         adiv.style.visibility = visString;
         aspan.innerHTML = msg;
    }
    if(typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
    

    指令碼會執行下列工作:

    • 定義 Sys.Application 類別之 load 事件的處理常式。接著,處理常式會為 PageRequestManager 類別的 initializeRequest 事件註冊一個名為 CheckStatus 的處理常式。

    • 定義 CheckStatus 處理常式以檢查目前是否正在執行非同步回傳,並判斷導致回傳之項目的名稱。

    • 定義 ActivateAlertDiv 函式,此函式會切換 <div> 項目的可視性,以顯示訊息。

搭配 UpdatePanel 控制項使用指令碼

此程序中,您要把您建立的指令碼,用到內含 UpdatePanel 控制項的網頁上。非同步回傳正在進行時,如果使用者按一下連結,這個指令碼就會取消回傳。

建立一個可以讓使用者取消回傳的網頁

  1. 建立新的單一檔案 ASP.NET Web 網頁,命名為 Default.aspx,並切換到 [設計] 檢視。

  2. 在工具箱的 [AJAX 擴充功能] 索引標籤中按兩下 ScriptManager 控制項,以便將該控制項加入至頁面。

  3. 在工具箱中按兩下 UpdatePanel 控制項,將其加入至頁面。

  4. 切換至 [原始碼] 檢視,並在網頁上 <head> 項目裡的 <style> 區塊中,加入下列樣式規則:

        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1{
           width: 400px;
           height: 200px;
           border: solid 1px gray;
        }
        div.AlertStyle {
          font-size: smaller;
          background-color: #FFC080;
          width: 400px;
          height: 20px;
          visibility: hidden;
        }
        </style>
    
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1{
           width: 400px;
           height: 200px;
           border: solid 1px gray;
        }
        div.AlertStyle {
          font-size: smaller;
          background-color: #FFC080;
          width: 400px;
          height: 20px;
          visibility: hidden;
        }
        </style>
    

    樣式規則會定義 UpdatePanel 控制項呈現之 <div> 項目的高度與寬度。樣式規則也會定義用以顯示進度訊息之巢狀 <div> 項目的外觀。

  5. 將下列標記加入至 <asp:UpdatePanel> 項目的 <ContentTemplate> 項目內:

    <asp:DataList ID="HeadlineList" >
        <HeaderTemplate>
        <strong>Headlines</strong>
        </HeaderTemplate>
        <ItemTemplate>
             <%# Eval("Value") %>
        </ItemTemplate>
        <FooterTemplate>
        </FooterTemplate>
        <FooterStyle HorizontalAlign="right" />
    </asp:DataList>
    <p style="text-align:right">
    <asp:Button ID="RefreshButton" 
                Text="Refresh" 
    
                OnClick="NewsClick_Handler" />
    </p>
    <div id="AlertDiv" class="AlertStyle">
    <span id="AlertMessage"></span> 
    &nbsp;&nbsp;&nbsp;&nbsp;
    <asp:LinkButton ID="CancelRefresh" >
    Cancel</asp:LinkButton>                      
    
    <asp:DataList ID="HeadlineList" >
        <HeaderTemplate>
        <strong>Headlines</strong>
        </HeaderTemplate>
        <ItemTemplate>
             <%# Eval("Value") %>
        </ItemTemplate>
        <FooterTemplate>
        </FooterTemplate>
        <FooterStyle HorizontalAlign="right" />
    </asp:DataList>
    <p style="text-align:right">
    <asp:Button ID="RefreshButton" 
                Text="Refresh" 
    
                OnClick="NewsClick_Handler" />
    </p>
    <div id="AlertDiv" class="AlertStyle">
    <span id="AlertMessage"></span> 
    &nbsp;&nbsp;&nbsp;&nbsp;
    <asp:LinkButton ID="CancelRefresh" >
    Cancel</asp:LinkButton>                      
    

    標記會執行下列工作:

    • 定義一個 DataList 控制項,此控制項的項目繫結到一個 Value 欄位,本程序稍候會將此欄位定義成 SortedList 物件。

    • 定義一個 Button 控制項,來引發非同步回傳。

    • 定義一個 <div> 項目,在非同步回傳時顯示訊息。<div> 項目並內含 LinkButton 控制項,可取消回傳。

  6. 在 <script > 項目裡加入下列伺服器程式碼,做為 Click 事件處理常式,以做為 UpdatePanel 控制項裡的 [重新整理] 按鈕。

    Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs)
        System.Threading.Thread.Sleep(2000)
        HeadlineList.DataSource = GetHeadlines()
        HeadlineList.DataBind()        
    End Sub
    
    protected void NewsClick_Handler(object sender, EventArgs e)
    {
        System.Threading.Thread.Sleep(2000);
        HeadlineList.DataSource = GetHeadlines();
        HeadlineList.DataBind();
    }
    

    程式碼會透過資料繫結來讀取並列出 DataList 控制項裡的標題。

    注意事項:

    在此教學課程中,Click 事件的處理常式會故意造成延遲。實際上,延遲並非由您造成。此延遲是因伺服器流量或需要長時間執行的伺服端程式碼 (例如,需長時間執行的資料庫查詢) 所造成。

  7. 在 <script> 項目內,加入下列程式碼,做為網頁的 Load 事件:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        If Not (IsPostBack) Then
            HeadlineList.DataSource = GetHeadlines()
            HeadlineList.DataBind()
        End If
    End Sub
    
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            HeadlineList.DataSource = GetHeadlines();
            HeadlineList.DataBind();
        }
    }
    

    此程式碼會檢查目前的要求是否需要傳回。如果不需要,DataList 控制項會繫結到一個標題清單 (非同步回傳期間,資料繫結會在 NewClick_Handler 方法時發生,您已於前一步驟建立了此方法)。

  8. 在 <script> 項目內,加入下列程式碼,以產生標題:

    ' Helper method to simulate news headline fetch.
    Private Function GetHeadlines() As SortedList
        Dim headlines As New SortedList()
        headlines.Add(1, "This is headline 1.")
        headlines.Add(2, "This is headline 2.")
        headlines.Add(3, "This is headline 3.")
        headlines.Add(4, "This is headline 4.")
        headlines.Add(5, "This is headline 5.")
        headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")")
        Return headlines
    End Function
    
    // Helper method to simulate news headline fetch.
    private SortedList GetHeadlines()
    {
        SortedList headlines = new SortedList();
        headlines.Add(1, "This is headline 1.");
        headlines.Add(2, "This is headline 2.");
        headlines.Add(3, "This is headline 3.");
        headlines.Add(4, "This is headline 4.");
        headlines.Add(5, "This is headline 5.");
        headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")");
        return headlines;
    }
    

    本教學課程中的標題建立成靜態清單。實際應用程式裡,標題可能會動態產生。

  9. 切換至 [設計] 檢視,確保網頁結構如下圖。

  10. 選取 ScriptManager 控制項。

  11. 在 [屬性] 視窗中,選取 [指令碼] 屬性,然後按一下省略符號 (…) 按鈕以顯示 [指令碼參考集合編輯器] 對話方塊。

  12. 按一下 [加入] 以加入指令碼參考。

  13. 將指令碼參考的 [路徑] 屬性設定為 CancelPostback.js,這是您先前建立的 JavaScript 檔案。

    使用 ScriptManagerScripts 集合加入指令碼參考,確保指令碼可於載入 Microsoft AJAX Library 後載入。

  14. 按一下 [確定] 關閉 [指令碼參考集合編輯器] 對話方塊。

  15. 儲存變更,然後按 CTRL+F5 在瀏覽器中檢視頁面。

  16. 按一下 [重新整理] 按鈕並等候面板重新整理。

    此時會顯示訊息,詢問您是否要取消回傳。

  17. 再按一下 [重新整理] 按鈕,訊息出現後,再按一下 [重新整理] 按鈕,並等候面板重新整理。

    訊息文字會改變,告訴您前一次重新整理仍在進行中。第二次重新整理會被忽略。

  18. 再按一下 [重新整理] 按鈕,訊息出現後,按一下 [取消] 連結以取消回傳。

    這次,UpdatePanel 控制項內顯示的時間不會變更,因為非同步回傳已取消。

    <%@ Page Language="VB" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script >
        Protected Sub NewsClick_Handler(ByVal sender As Object, ByVal e As EventArgs)
            System.Threading.Thread.Sleep(2000)
            HeadlineList.DataSource = GetHeadlines()
            HeadlineList.DataBind()        
        End Sub
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
            If Not (IsPostBack) Then
                HeadlineList.DataSource = GetHeadlines()
                HeadlineList.DataBind()
            End If
        End Sub
        ' Helper method to simulate news headline fetch.
        Private Function GetHeadlines() As SortedList
            Dim headlines As New SortedList()
            headlines.Add(1, "This is headline 1.")
            headlines.Add(2, "This is headline 2.")
            headlines.Add(3, "This is headline 3.")
            headlines.Add(4, "This is headline 4.")
            headlines.Add(5, "This is headline 5.")
            headlines.Add(6, "(Last updated on " & DateTime.Now.ToString() & ")")
            Return headlines
        End Function
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" >
        <title>Canceling Postback Example</title>
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1{
           width: 400px;
           height: 200px;
           border: solid 1px gray;
        }
        div.AlertStyle {
          font-size: smaller;
          background-color: #FFC080;
          width: 400px;
          height: 20px;
          visibility: hidden;
        }
        </style>
    </head>
    <body>
        <form id="form1" >
            <div >
            <asp:ScriptManager ID="ScriptManager1" >
            <Scripts>
            <asp:ScriptReference Path="CancelPostback.js" />
            </Scripts>
            </asp:ScriptManager>
            <asp:UpdatePanel  ID="UpdatePanel1" runat="Server" >
                <ContentTemplate>
                    <asp:DataList ID="HeadlineList" >
                        <HeaderTemplate>
                        <strong>Headlines</strong>
                        </HeaderTemplate>
                        <ItemTemplate>
                             <%# Eval("Value") %>
                        </ItemTemplate>
                        <FooterTemplate>
                        </FooterTemplate>
                        <FooterStyle HorizontalAlign="right" />
                    </asp:DataList>
                    <p style="text-align:right">
                    <asp:Button ID="RefreshButton" 
                                Text="Refresh" 
    
                                OnClick="NewsClick_Handler" />
                    </p>
                    <div id="AlertDiv" class="AlertStyle">
                    <span id="AlertMessage"></span> 
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <asp:LinkButton ID="CancelRefresh" >
                    Cancel</asp:LinkButton>                      
                </ContentTemplate>
            </asp:UpdatePanel>
            </div>
        </form>
    </body>
    </html>
    
    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <script >
        protected void NewsClick_Handler(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(2000);
            HeadlineList.DataSource = GetHeadlines();
            HeadlineList.DataBind();
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                HeadlineList.DataSource = GetHeadlines();
                HeadlineList.DataBind();
            }
        }
        // Helper method to simulate news headline fetch.
        private SortedList GetHeadlines()
        {
            SortedList headlines = new SortedList();
            headlines.Add(1, "This is headline 1.");
            headlines.Add(2, "This is headline 2.");
            headlines.Add(3, "This is headline 3.");
            headlines.Add(4, "This is headline 4.");
            headlines.Add(5, "This is headline 5.");
            headlines.Add(6, "(Last updated on " + DateTime.Now.ToString() + ")");
            return headlines;
        }
    </script>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head >
        <title>Canceling Postback Example</title>
        <style type="text/css">
        body {
            font-family: Tahoma;
        }
        #UpdatePanel1{
           width: 400px;
           height: 200px;
           border: solid 1px gray;
        }
        div.AlertStyle {
          font-size: smaller;
          background-color: #FFC080;
          width: 400px;
          height: 20px;
          visibility: hidden;
        }
        </style>
    </head>
    <body>
        <form id="form1" >
            <div >
            <asp:ScriptManager ID="ScriptManager1" >
            <Scripts>
            <asp:ScriptReference Path="CancelPostback.js" />
            </Scripts>
            </asp:ScriptManager>
            <asp:UpdatePanel  ID="UpdatePanel1" runat="Server" >
                <ContentTemplate>
                    <asp:DataList ID="HeadlineList" >
                        <HeaderTemplate>
                        <strong>Headlines</strong>
                        </HeaderTemplate>
                        <ItemTemplate>
                             <%# Eval("Value") %>
                        </ItemTemplate>
                        <FooterTemplate>
                        </FooterTemplate>
                        <FooterStyle HorizontalAlign="right" />
                    </asp:DataList>
                    <p style="text-align:right">
                    <asp:Button ID="RefreshButton" 
                                Text="Refresh" 
    
                                OnClick="NewsClick_Handler" />
                    </p>
                    <div id="AlertDiv" class="AlertStyle">
                    <span id="AlertMessage"></span> 
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <asp:LinkButton ID="CancelRefresh" >
                    Cancel</asp:LinkButton>                      
                </ContentTemplate>
            </asp:UpdatePanel>
            </div>
        </form>
    </body>
    </html>
    

檢閱

本教學課程示範如何撰寫 JavaScript 程式碼來取消非同步回傳。這個指令碼為 PageRequestManager 類別的 initializeRequest 事件提供一個處理常式。在 initializeRequest 事件中,您可以決定要由哪一個項目來引發回傳,以及回傳是否正在進行中。之後您就可以採取適當動作。本教學課程中的程式碼顯示一個內含取消按鈕的 <div> 項目。

如果希望能自動顯示 UpdatePanel 控制項狀態,您可以使用 UpdateProgress 控制項。如需詳細資訊,請參閱UpdateProgress 控制項簡介

請參閱

工作

在用戶端指令碼中撰寫 UpdateProgress 控制項程式

概念

使用 PageRequestManager 事件

參考

Sys.WebForms.PageRequestManager 類別

Sys.WebForms.PageRequestManager initializeRequest 事件