Поделиться через


Отмена асинхронной обратной передачи

Обновлен: Ноябрь 2007

Асинхронная обратная передача реализуется в ASP.NET с помощью серверных веб-элементов управления UpdatePanel .NET, размещаемых на странице. Элемент управления UpdatePanel позволяет не обновлять страницу целиком с каждой обратной передачей, что улучшает взаимодействие с пользователем. За управление событиями в жизненном цикле клиентской страницы, обеспечивающее асинхронную обратную передачу, отвечает класс обозревателя Sys.WebForms.PageRequestManager в библиотеке Microsoft AJAX (библиотека). Ход асинхронной обратной передачи можно настроить путем обработки событий, предоставленных классом PageRequestManager.

В данном пошаговом руководстве будет использоваться событие initializeRequest класса PageRequestManager для отмены выполняемой в данный момент асинхронной обратной передачи.

Сведения о последовательности возникновения событий в классе PageRequestManager см. в разделе Работа с событиями класса PageRequestManager.

Обязательные компоненты

Для реализации процедур в собственной среде разработки вам потребуются:

  • Microsoft Visual Studio 2005 или Microsoft Visual Web Developer, экспресс-выпуск.

  • Веб-узел ASP.NET с поддержкой AJAX.

Создание сценария, отменяющего обратные передачи

Можно начать с создания кода ECMAScript (JavaScript), управляющего асинхронной обратной передачей в обозревателе.

Создание кода JavaScript для отмены обратной передачи

  1. Добавьте новый файл JScript с именем CancelPostback.js в веб-узел ASP.NET.

  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();
    

    Сценарий выполняет следующие задачи:

    • Определяет обработчик для события load класса Sys.Application. Этот обработчик, в свою очередь, регистрирует обработчик с именем CheckStatus для события initializeRequest класса PageRequestManager.

    • Определяет обработчик CheckStatus, чтобы проверять, выполняется ли в данный момент асинхронная обратная передача, и чтобы определять имя элемента, вызвавшего обратную передачу.

    • Определяет функцию ActivateAlertDiv, переключающую видимость элемента <div>, используемого для отображения сообщений.

Использование сценария с элементом управления UpdatePanel

В этой процедуре будет использоваться сценарий, созданный на странице, содержащей элемент управления UpdatePanel. Сценарий отменит обратную передачу, если пользователь щелкает ссылку во время выполнения асинхронной обратной передачи.

Создание страницы, на которой пользователи смогут отменять обратную передачу

  1. Создайте новую однофайловую веб-страницу ASP.NET с именем Default.aspx и переключитесь в режим конструктора.

  2. На вкладке AJAX-расширения панели элементов дважды щелкните элемент управления ScriptManager, чтобы добавить его на страницу.

    Урок UpdatePanel

  3. В панели элементов дважды щелкните элемент управления UpdatePanel, чтобы добавить его на страницу.

    Урок UpdatePanel

  4. Перейдите в режим исходного кода и добавьте следующие правила стилей к блоку <style> в элементе <head> страницы:

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

    Правила стилей определяют высоту и ширину элемента <div>, отрисовываемого элементом управления UpdatePanel. Также правила определяют внешний вид вложенного элемента <div>, отображающего сообщение о ходе выполнения.

  5. Добавьте следующую разметку в элемент <ContentTemplate> элемента <asp:UpdatePanel>:

    <asp:DataList ID="HeadlineList" runat="server">
        <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" 
                runat="server" 
                OnClick="NewsClick_Handler" />
    </p>
    <div id="AlertDiv" class="AlertStyle">
    <span id="AlertMessage"></span> 
    &nbsp;&nbsp;&nbsp;&nbsp;
    <asp:LinkButton ID="CancelRefresh" runat="server">
    Cancel</asp:LinkButton>                      
    
    <asp:DataList ID="HeadlineList" runat="server">
        <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" 
                runat="server" 
                OnClick="NewsClick_Handler" />
    </p>
    <div id="AlertDiv" class="AlertStyle">
    <span id="AlertMessage"></span> 
    &nbsp;&nbsp;&nbsp;&nbsp;
    <asp:LinkButton ID="CancelRefresh" runat="server">
    Cancel</asp:LinkButton>                      
    

    Разметка выполняет следующие задачи:

    • Определяет элемент управления DataList, элементы которого привязываются к полю Value, которое будет определено позже в этой процедуре как объект SortedList.

    • Определяет элемент управления Button, вызывающий асинхронную обратную передачу.

    • Определяет элемент <div>, который будет использоваться для отображения сообщения во время асинхронной обратной передачи. Элемент <div> также содержит элемент управления LinkButton, который делает возможным отмену обратной передачи.

  6. В элементе <script runat="server"> добавьте следующий серверный код в качестве обработчика событий 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.

    Bb398789.alert_note(ru-ru,VS.90).gifПримечание.

    Обработчик событий 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. Переключитесь в режим конструктора и убедитесь, что страница напоминает следующий рисунок.

    Урок UpdatePanel

  10. Выберите элемент управления ScriptManager.

  11. В окне "Свойства" выберите свойство Сценарии и нажмите кнопку с многоточием ("…"), чтобы отобразить диалоговое окно Редактор коллекции ScriptReference.

  12. Нажмите кнопку Добавить, чтобы добавить ссылку на сценарий.

  13. Задайте для свойства Path ссылки сценария значение CancelPostback.js — это созданный ранее файл JavaScript.

    Добавление ссылки сценария с помощью коллекции Scripts объекта ScriptManager гарантирует, что сценарий загружается после загрузки Microsoft AJAX (библиотека).

    Урок UpdatePanel

  14. Нажмите кнопку ОК, чтобы закрыть диалоговое окно Редактор коллекции ScriptReference.

  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 runat="server">
        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" runat="server">
        <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" runat="server">
            <div >
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
            <asp:ScriptReference Path="CancelPostback.js" />
            </Scripts>
            </asp:ScriptManager>
            <asp:UpdatePanel  ID="UpdatePanel1" runat="Server" >
                <ContentTemplate>
                    <asp:DataList ID="HeadlineList" runat="server">
                        <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" 
                                runat="server" 
                                OnClick="NewsClick_Handler" />
                    </p>
                    <div id="AlertDiv" class="AlertStyle">
                    <span id="AlertMessage"></span> 
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <asp:LinkButton ID="CancelRefresh" runat="server">
                    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 runat="server">
        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 runat="server">
        <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" runat="server">
            <div >
            <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
            <asp:ScriptReference Path="CancelPostback.js" />
            </Scripts>
            </asp:ScriptManager>
            <asp:UpdatePanel  ID="UpdatePanel1" runat="Server" >
                <ContentTemplate>
                    <asp:DataList ID="HeadlineList" runat="server">
                        <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" 
                                runat="server" 
                                OnClick="NewsClick_Handler" />
                    </p>
                    <div id="AlertDiv" class="AlertStyle">
                    <span id="AlertMessage"></span> 
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <asp:LinkButton ID="CancelRefresh" runat="server">
                    Cancel</asp:LinkButton>                      
                </ContentTemplate>
            </asp:UpdatePanel>
            </div>
        </form>
    </body>
    </html>
    

Итог

В этом пошаговом руководстве демонстрируется, как создать код JavaScript, отменяющий асинхронную обратную передачу. Сценарий предоставляет обработчик событий initializeRequest класса PageRequestManager. В событии initializeRequest можно определить, какой элемент вызвал обратную передачу, и началось ли уже ее выполнение. Затем можно предпринять необходимые меры. В руководстве код отображает элемент <div>, содержащий кнопку отмены.

Для автоматического отображения состояния элемента управления UpdatePanel можно использовать элемент управления UpdateProgress. Дополнительные сведения см. в разделе Знакомство с элементом управления UpdateProgress.

См. также

Задачи

Программирование элементов управления UpdateProgress в клиентском сценарии

Основные понятия

Работа с событиями класса PageRequestManager

Ссылки

Класс Sys.WebForms.PageRequestManager

Событие Sys.WebForms.PageRequestManager initializeRequest