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


Общие сведения о триггерах UpdatePanel ASP.NET AJAX

Скотт Кейт

При работе в редакторе разметки в Visual Studio вы можете заметить (от IntelliSense), что элемент управления UpdatePanel имеет два дочерних элемента. Одним из которых является элемент Triggers, который задает элементы управления на странице (или пользовательский элемент управления, если вы используете его), который активирует частичную отрисовку элемента управления UpdatePanel, в котором находится элемент .

Введение

Технология microsoft ASP.NET предоставляет объектно-ориентированную и управляемую событиями модель программирования и объединяет ее с преимуществами скомпилированного кода. Однако ее модель обработки на стороне сервера имеет несколько недостатков, присущих технологии, многие из которых можно устранить с помощью новых функций, включенных в расширения MICROSOFT ASP.NET 3.5 AJAX. Эти расширения обеспечивают множество новых функциональных возможностей клиента, включая частичную отрисовку страниц без полного обновления страницы, возможность доступа к веб-службам через клиентский скрипт (включая API профилирования ASP.NET) и обширный КЛИЕНТСКИй API, предназначенный для зеркало многих схем управления, которые можно увидеть в ASP.NET наборе элементов управления на стороне сервера.

В этом техническом документе рассматриваются функциональные возможности триггеров XML компонента ASP.NET AJAX UpdatePanel . Триггеры XML предоставляют детализированный контроль над компонентами, которые могут вызвать частичную отрисовку для определенных элементов управления UpdatePanel.

Этот технический документ основан на бета-версии 2 платформа .NET Framework 3.5 и Visual Studio 2008. Расширения ASP.NET AJAX, ранее сборка надстройки, предназначенная для ASP.NET 2.0, теперь интегрированы в библиотеку базовых классов платформа .NET Framework. В этом техническом документе также предполагается, что вы будете работать с Visual Studio 2008, а не Visual Web Developer Express, и предоставляет пошаговые руководства в соответствии с пользовательским интерфейсом Visual Studio (хотя списки кода будут полностью совместимы независимо от среды разработки).

Триггеры

Триггеры для заданного UpdatePanel по умолчанию автоматически включают все дочерние элементы управления, вызывающие обратную передачу, включая (например,) элементы управления TextBox со свойством AutoPostBacktrue. Однако триггеры также можно включить декларативно с помощью разметки; Это делается в <triggers> разделе объявления элемента управления UpdatePanel. Хотя доступ к триггерам можно получить через Triggers свойство коллекции, рекомендуется регистрировать все триггеры частичной отрисовки во время выполнения (например, если элемент управления недоступен во время разработки) с помощью RegisterAsyncPostBackControl(Control) метода объекта ScriptManager для страницы в Page_Load рамках события . Помните, что pages не имеют отслеживания состояния, поэтому необходимо повторно регистрировать эти элементы управления при каждом их создании.

Автоматическое включение дочерних триггеров также можно отключить (чтобы дочерние элементы управления, создающие обратную передачу, не запускали автоматически частичные отрисовки), установив для ChildrenAsTriggers свойства значение false. Это обеспечивает максимальную гибкость при назначении конкретных элементов управления, которые могут вызывать отрисовку страницы, и рекомендуется, чтобы разработчик мог реагировать на событие, а не обрабатывать любые события, которые могут возникнуть.

Обратите внимание, что при вложенных элементах управления UpdatePanel, если параметру UpdateMode присвоено значение Условный, если активируется дочерний элемент UpdatePanel, а родительский — нет, то обновляется только дочерний элемент UpdatePanel. Однако при обновлении родительского элемента UpdatePanel также будет обновлен дочерний Элемент UpdatePanel.

Элемент <Triggers>

При работе в редакторе разметки в Visual Studio вы можете заметить (из IntelliSense), что элемент управления имеет два дочерних UpdatePanel элемента. Наиболее часто встречающимся элементом является <ContentTemplate> элемент , который по сути инкапсулирует содержимое, которое будет храниться на панели обновления (содержимое, для которого мы включаем частичную отрисовку). Другим элементом <Triggers> является элемент , который задает элементы управления на странице (или пользовательский элемент управления, если вы используете его), который активирует частичную отрисовку элемента управления UpdatePanel, в котором <находится элемент Triggers> .

Элемент <Triggers> может содержать любое число каждого из двух дочерних узлов: <asp:AsyncPostBackTrigger> и <asp:PostBackTrigger>. Они принимают два атрибута, ControlID и , и EventNameмогут указывать любой элемент управления в текущей единице инкапсуляции (например, если элемент управления UpdatePanel находится в пользовательском веб-элементе управления, не следует пытаться ссылаться на элемент управления на странице, на котором будет находиться пользовательский элемент управления).

Элемент <asp:AsyncPostBackTrigger> особенно полезен тем, что он может нацелиться на любое событие из элемента управления, существующего как дочерний элемент любого элемента управления UpdatePanel в блоке инкапсуляции, а не только на UpdatePanel, под которым этот триггер является дочерним. Таким образом, можно сделать любой элемент управления для активации частичного обновления страницы.

Аналогичным образом, <asp:PostBackTrigger> элемент можно использовать для запуска частичной отрисовки страницы, но для этого требуется полный круговой путь к серверу. Этот элемент триггера также можно использовать для принудительной отрисовки полной страницы, когда элемент управления в противном случае обычно активирует частичную отрисовку страницы (например, если элемент Button управления существует в элементе <ContentTemplate> элемента управления UpdatePanel). Опять же, элемент PostBackTrigger может указать любой элемент управления, который является дочерним по отношению к любому элементу управления UpdatePanel в текущей единице инкапсуляции.

<Ссылка на элемент Triggers>

Потомки разметки:

Тег Описание
<asp:AsyncPostBackTrigger> Указывает элемент управления и событие, которые вызовут частичное обновление страницы для UpdatePanel, содержащего эту ссылку на триггер.
<asp:PostBackTrigger> Указывает элемент управления и событие, которое приведет к полному обновлению страницы (полного обновления страницы). Этот тег можно использовать для принудительного полного обновления, если элемент управления в противном случае активирует частичную отрисовку.

Пошаговое руководство. Триггеры cross-UpdatePanel

  1. Создайте страницу ASP.NET с объектом ScriptManager, заданным для частичной отрисовки. Добавьте на эту страницу два элемента обновления UpdatePanels. В первом включите элемент управления Label (Label1) и два элемента управления Button (Button1 и Button2). Button1 должен иметь значение Click to Update Both (Нажмите, чтобы обновить оба), а Button2 — кнопку Click to Update This (Нажмите, чтобы обновить это) или что-то в этом направлении. Во втором UpdatePanel включите только элемент управления Label (Label2), но задайте для его свойства ForeColor значение, отличное от значения по умолчанию.
  2. Задайте для свойства UpdateMode обоих тегов UpdatePanel значение Условный.

Листинг 1. Разметка для default.aspx:



<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
   <head runat="server">
      <title>Untitled Page</title>
   </head>
   <body>
      <form id="form1" runat="server">
         <asp:ScriptManager EnablePartialRendering="true"
            ID="ScriptManager1" runat="server"></asp:ScriptManager>
         <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label1" runat="server" />
                  <br />
                  <asp:Button ID="Button1" runat="server"
                     Text="Update Both Panels" OnClick="Button1_Click" />
                  <asp:Button ID="Button2" runat="server"
                     Text="Update This Panel" OnClick="Button2_Click" />
               </ContentTemplate>
            </asp:UpdatePanel>
            <asp:UpdatePanel ID="UpdatePanel2" runat="server"
               UpdateMode="Conditional">
               <ContentTemplate>
                  <asp:Label ID="Label2" runat="server" ForeColor="red" />
               </ContentTemplate>
               <Triggers>
                  <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
               </Triggers>
            </asp:UpdatePanel>
         </div>
      </form>
   </body>
</html>

  1. В обработчике событий Click для Button1 задайте для параметра Label1.Text и Label2.Text значение, зависящее от времени (например, DateTime.Now.ToLongTimeString()). Для обработчика событий Click для Button2 задайте только значение Label1.Text, зависящее от времени.

Листинг 2. Код программной части (обрезанный) в файле default.aspx.cs:

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
        Label2.Text = DateTime.Now.ToLongTimeString();
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        Label1.Text = DateTime.Now.ToLongTimeString();
    }
}
  1. Нажмите клавишу F5 для сборки и запуска проекта. Обратите внимание, что при нажатии кнопки Обновить обе панели обе метки изменяют текст; Однако при нажатии кнопки Обновить эту панель обновляется только Label1.

Снимок экрана: первая кнопка с состоянием

(Щелкните для просмотра полноразмерного изображения)

Под капотом

Используя только что созданный пример, мы можем взглянуть на то, что делает ASP.NET AJAX и как работают наши межпанельные триггеры UpdatePanel. Для этого мы будем работать с созданным html-кодом страницы, а также с расширением Mozilla Firefox с именем FireBug . С его помощью мы можем легко изучить обратные передачи AJAX. Мы также будем использовать инструмент .NET Reflector от Lutz Roeder. Оба этих средства находятся в свободном доступе в Интернете, и их можно найти с помощью поиска в Интернете.

Изучение исходного кода страницы не показывает почти ничего необычного; Элементы управления UpdatePanel отображаются в виде <div> контейнеров, и мы видим, что ресурс скрипта включает в <asp:ScriptManager>себя . Существуют также некоторые новые вызовы, относящиеся к AJAX, к PageRequestManager, которые являются внутренними для клиентской библиотеки сценариев AJAX. Наконец, мы видим два контейнера UpdatePanel — один с кнопками отображения <input> с двумя <asp:Label> элементами управления, отображаемыми в виде <span> контейнеров. (Если проверить дерево DOM в FireBug, вы увидите, что метки неактивны, чтобы указать, что они не создают видимое содержимое.

Нажмите кнопку Обновить эту панель и обратите внимание, что в верхней части UpdatePanel будет обновлено текущее время сервера. В FireBug выберите вкладку Консоль, чтобы изучить запрос. Сначала изучите параметры запроса POST:

Снимок экрана: диалоговое окно Firebug с выбранной консолью.

(Щелкните для просмотра полноразмерного изображения)

Обратите внимание, что UpdatePanel указал в коде AJAX на стороне сервера, какое дерево элементов управления было запущено с помощью параметра Button1UpdatePanel1 ScriptManager1 элемента управления. Теперь нажмите кнопку Обновить обе панели. Затем, проверив ответ, мы увидим ряд переменных, разделенных каналом, заданных в строке; В частности, мы видим, что top UpdatePanel, , содержит полный html-код, UpdatePanel1отправленный в браузер. Клиентская библиотека скриптов AJAX заменяет исходное HTML-содержимое UpdatePanel новым содержимым через .innerHTML свойство , поэтому сервер отправляет измененное содержимое с сервера в виде HTML.

Теперь нажмите кнопку Обновить обе панели и проверьте результаты с сервера. Результаты очень похожи : оба Элемента Обновления получают новый HTML-код с сервера. Как и при предыдущем обратном вызове, отправляется дополнительное состояние страницы.

Как мы видим, так как для обратной передачи AJAX не используется специальный код, библиотека клиентских скриптов AJAX может перехватывать обратные передачи форм без дополнительного кода. Серверные элементы управления автоматически используют JavaScript, чтобы не отправлять форму автоматически. ASP.NET автоматически внедряет код для проверки формы и состояния, в основном благодаря автоматическому включению ресурсов скрипта, классу PostBackOptions и классу ClientScriptManager.

Например, рассмотрим элемент управления CheckBox; проверьте дизассемблированное представление класса в отражателе .NET. Для этого убедитесь, что сборка System.Web открыта, и перейдите к классу System.Web.UI.WebControls.CheckBox , открыв RenderInputTag метод . Найдите условный объект, проверяющий AutoPostBack свойство :

Снимок экрана: код, начинающийся с кнопки Click equals .

(Щелкните для просмотра полноразмерного изображения)

Если для элемента управления включена CheckBox автоматическая обратная передача (с помощью свойства AutoPostBack имеет значение true), результирующий <input> тег отображается с ASP.NET скриптом обработки событий в его onclick атрибуте. Таким образом, перехват отправки формы позволяет ASP.NET AJAX внедряться на страницу неинструзивно, что помогает избежать любых возможных критических изменений, которые могут произойти, используя замену строки, возможно, неточным. Кроме того, это позволяет любому пользовательскому элементу управления ASP.NET использовать возможности ASP.NET AJAX без дополнительного кода для поддержки его использования в контейнере UpdatePanel.

Функциональные <triggers> возможности соответствуют значениям, инициализированным в вызове PageRequestManager для _updateControls (обратите внимание, что клиентская библиотека сценариев AJAX ASP.NET использует соглашение о том, что методы, события и имена полей, начинающиеся с символа подчеркивания, помечаются как внутренние и не предназначены для использования за пределами самой библиотеки). С его помощью мы можем наблюдать, какие элементы управления предназначены для обратной передачи AJAX.

Например, давайте добавим на страницу два дополнительных элемента управления, оставив один за пределами UpdatePanels, а один — в UpdatePanel. Мы добавим элемент управления CheckBox в верхнюю область UpdatePanel и удалите DropDownList с несколькими цветами, определенными в списке. Вот новая разметка:

Листинг 3. Новая разметка

<%@ Page Language="C#" AutoEventWireup="true"
 CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
 <head id="Head1" runat="server">
 <title>Untitled Page</title>
 </head>
 <body>
 <form id="form1" runat="server">
 <asp:ScriptManager EnablePartialRendering="true"
 ID="ScriptManager1" runat="server"></asp:ScriptManager>
 <div>
 <asp:UpdatePanel ID="UpdatePanel1" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label1" runat="server" /><br />
 <asp:Button ID="Button1" runat="server"
 Text="Update Both Panels" OnClick="Button1_Click" />
 <asp:Button ID="Button2" runat="server"
 Text="Update This Panel" OnClick="Button2_Click" />
 <asp:CheckBox ID="cbDate" runat="server"
 Text="Include Date" AutoPostBack="false"
 OnCheckedChanged="cbDate_CheckedChanged" />
 </ContentTemplate>
 </asp:UpdatePanel>
 <asp:UpdatePanel ID="UpdatePanel2" runat="server"
 UpdateMode="Conditional">
 <ContentTemplate>
 <asp:Label ID="Label2" runat="server"
 ForeColor="red" />
 </ContentTemplate>
 <Triggers>
 <asp:AsyncPostBackTrigger ControlID="Button1" 
 EventName="Click" />
 <asp:AsyncPostBackTrigger ControlID="ddlColor" 
 EventName="SelectedIndexChanged" />
 </Triggers>
 </asp:UpdatePanel>
 <asp:DropDownList ID="ddlColor" runat="server"
 AutoPostBack="true"
 OnSelectedIndexChanged="ddlColor_SelectedIndexChanged">
 <asp:ListItem Selected="true" Value="Red" />
 <asp:ListItem Value="Blue" />
 <asp:ListItem Value="Green" />
 </asp:DropDownList>
 </div>
 </form>
 </body>
</html>

А вот новый код программной части:

Листинг 4. Код программной части

public partial class _Default : System.Web.UI.Page
{
    protected void Button1_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
            Label2.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
            Label2.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        if (cbDate.Checked)
        {
            Label1.Text = DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
        }
        else
        {
            Label1.Text = DateTime.Now.ToLongTimeString();
        }
    }
    protected void cbDate_CheckedChanged(object sender, EventArgs e)
    {
        cbDate.Font.Bold = cbDate.Checked;
    }
    protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
    {
        Color c = Color.FromName(ddlColor.SelectedValue);
        Label2.ForeColor = c;
    }
}

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

Снимок экрана: веб-браузер с именем Untitled Page и раскрывающийся список с выбранным цветом Синий под кнопкой Обновить обе панели.

(Щелкните для просмотра полноразмерного изображения)

Как видно на приведенном выше снимке экрана, последняя кнопка для нажатия была правильной кнопкой Обновить эту панель, которая обновила верхний момент независимо от нижнего времени. Дата также была отключена между щелчками, так как дата отображается в нижней метке. Наконец, интерес представляет цвет нижней метки: он был обновлен позднее, чем текст метки, который показывает, что состояние элемента управления важно, и пользователи ожидают, что оно будет сохранено с помощью обратной передачи AJAX. Однако время не было обновлено. Время автоматически повторялось за счет сохранения поля __VIEWSTATE страницы, интерпретируемого средой выполнения ASP.NET при повторной отрисовки элемента управления на сервере. Код сервера ASP.NET AJAX не распознает, в каких методах изменяется состояние элементов управления; он просто повторяется из состояния представления, а затем запускает соответствующие события.

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

Итоги

Элемент управления UpdatePanel ASP.NET расширений AJAX является универсальным и может использовать ряд методов для определения событий элемента управления, которые должны привести к его обновлению. Он поддерживает автоматическое обновление дочерними элементами управления, но также может реагировать на события элементов управления в других местах на странице.

Чтобы уменьшить потенциальную нагрузку на серверную обработку, рекомендуется ChildrenAsTriggers задать свойству falseUpdatePanel значение , а события должны быть выбраны, а не включены по умолчанию. Это также предотвращает ненужные события, которые могут вызвать потенциально нежелательные последствия, включая проверку и изменения полей ввода. Эти типы ошибок может быть трудно изолировать, так как страница обновляется прозрачно для пользователя, и поэтому причина может быть неясным.

Изучив внутреннюю работу модели после перехвата ASP.NET ajax, мы смогли определить, что в ней используется платформа, уже предоставляемая ASP.NET. При этом он сохраняет максимальную совместимость с элементами управления, разработанными на той же платформе, и минимально вторгается в любой дополнительный Код JavaScript, написанный для страницы.

Биография

Роб Павеза (Rob Paveza) — старший разработчик приложений .NET в Terralever (www.terralever.com), ведущей компании по интерактивному маркетингу в Темпе, штат Северная Азия. Он может быть доступен по адресу robpaveza@gmail.com, и его блог находится по адресу http://geekswithblogs.net/robp/.

Скотт Кейт работает с веб-технологиями Майкрософт с 1997 года и является президентом myKB.com (www.myKB.com), где он специализируется на написании ASP.NET приложений, ориентированных на решения базы знаний. Скотт можно связаться по электронной почте по адресу scott.cate@myKB.com или его блог на ScottCate.com