Sdílet prostřednictvím


Principy aktivačních událostí UpdatePanel technologie ASP.NET AJAX

Scott Cate

Při práci v editoru značek v sadě Visual Studio si můžete všimnout (z IntelliSense), že existují dva podřízené prvky ovládacího prvku UpdatePanel. Jedním z nich je Triggers element, který určuje ovládací prvky na stránce (nebo uživatelský ovládací prvek, pokud používáte jeden), který aktivuje částečné vykreslení UpdatePanel ovládacího prvku, ve kterém se nachází prvek.

Úvod

Technologie ASP.NET od Microsoftu přináší objektově orientovaný programovací model řízený událostmi a spojuje ho s výhodami zkompilovaného kódu. Jeho model zpracování na straně serveru má však několik nevýhod, které jsou součástí technologie, z nichž mnohé lze vyřešit pomocí nových funkcí, které jsou součástí rozšíření Microsoft ASP.NET 3.5 AJAX. Tato rozšíření umožňují mnoho nových bohatých klientských funkcí, včetně částečného vykreslování stránek bez nutnosti aktualizace celé stránky, možnosti přístupu k webovým službám prostřednictvím klientského skriptu (včetně rozhraní API pro profilaci ASP.NET) a rozsáhlého rozhraní API na straně klienta navrženého tak, aby zrcadlil mnoho schémat ovládacích prvků, která se zobrazují v ASP.NET sadě ovládacích prvků na straně serveru.

Tento dokument white paper zkoumá funkci triggerů XML komponenty ASP.NET AJAX UpdatePanel . Triggery XML poskytují podrobnou kontrolu nad komponentami, které mohou způsobit částečné vykreslování pro konkrétní UpdatePanel ovládací prvky.

Tento dokument white paper je založený na verzi Beta 2 rozhraní .NET Framework 3.5 a sady Visual Studio 2008. Rozšíření ASP.NET AJAX, dříve doplňkové sestavení cílené na ASP.NET 2.0, jsou nyní integrovány do knihovny základních tříd rozhraní .NET Framework. Tento dokument white paper také předpokládá, že budete pracovat se sadou Visual Studio 2008, nikoli se sadou Visual Web Developer Express, a poskytnete návody podle uživatelského rozhraní sady Visual Studio (i když výpisy kódu budou zcela kompatibilní bez ohledu na vývojové prostředí).

Triggery

Triggery pro daný UpdatePanel ve výchozím nastavení automaticky obsahují všechny podřízené ovládací prvky, které vyvolávají zpětné volání, včetně (například) TextBox ovládacích prvků, které mají jejich AutoPostBack vlastnost nastavenou na true. Aktivační události však mohou být také zahrnuty deklarativně pomocí značky; to se provádí v <triggers> části UpdatePanel deklarace ovládacího prvku. I když je možné k triggerům přistupovat prostřednictvím Triggers vlastnosti kolekce, doporučuje se zaregistrovat jakékoli částečné aktivační události vykreslování za běhu (například pokud ovládací prvek není k dispozici v době návrhu) pomocí RegisterAsyncPostBackControl(Control) metody objektu ScriptManager pro vaši stránku v rámci Page_Load události. Mějte na paměti, že pages jsou bezstavové, a proto byste tyto ovládací prvky měli při každém vytvoření znovu zaregistrovat.

Automatické zahrnutí podřízené aktivační události lze také zakázat (aby podřízené ovládací prvky, které vytvářejí zpětné odeslání, automaticky neaktivují částečné vykreslení) nastavením ChildrenAsTriggers vlastnosti na false. To vám umožňuje největší flexibilitu při přiřazování konkrétních ovládacích prvků, které můžou vyvolat vykreslení stránky, a doporučuje se, aby vývojáři povolili reagovat na událost, a nemuseli zpracovávat události, které by mohly nastat.

Všimněte si, že při UpdatePanel ovládací prvky jsou vnořené, když UpdateMode je nastavena na Podmíněné, pokud je aktivován podřízený UpdatePanel, ale nadřazený není, pak se aktualizuje pouze podřízený UpdatePanel. Pokud je však nadřazený UpdatePanel aktualizován, bude aktualizována také podřízený UpdatePanel.

Element <Triggers>

Při práci v editoru značek v sadě Visual Studio si můžete všimnout (z IntelliSense), že ovládací prvek UpdatePanel obsahuje dva podřízené prvky. Nejčastěji používaným prvkem je <ContentTemplate> element , který v podstatě zapouzdřuje obsah, který bude uložen na panelu aktualizací (obsah, pro který povolujeme částečné vykreslování). Druhý element je <Triggers> element, který určuje ovládací prvky na stránce (nebo uživatelský ovládací prvek, pokud používáte jeden), který aktivuje částečné vykreslení UpdatePanel ovládacího prvku, ve kterém <se nachází Triggers> element.

Element <Triggers> může obsahovat libovolné číslo každého ze dvou podřízených uzlů: <asp:AsyncPostBackTrigger> a <asp:PostBackTrigger>. Oba přijímají dva atributy, ControlID a EventName, a mohou zadat libovolný ovládací prvek v rámci aktuální jednotky zapouzdření (například pokud se ovládací prvek UpdatePanel nachází v ovládacím prvku Web User Control, neměli byste se pokoušet odkazovat na ovládací prvek na stránce, na které bude umístěný uživatelský ovládací prvek).

Element <asp:AsyncPostBackTrigger> je zvláště užitečný v tom, že může cílit na libovolnou událost z ovládacího prvku, který existuje jako podřízený prvek jakékoli UpdatePanel ovládacího prvku v jednotce zapouzdření, nejen UpdatePanel, pod kterým je tato aktivační událost podřízena. Proto lze vytvořit jakýkoli ovládací prvek, který aktivuje částečnou aktualizaci stránky.

Podobně <asp:PostBackTrigger> lze prvek použít k aktivaci částečného vykreslení stránky, ale vyžaduje úplné odezvu na server. Tento aktivační prvek lze také použít k vynucení vykreslení celé stránky, pokud by ovládací prvek jinak normálně aktivoval částečné vykreslení stránky (například když Button ovládací prvek existuje v <ContentTemplate> elementu ovládacího prvku UpdatePanel). Opět PostBackTrigger element může určit jakýkoli ovládací prvek, který je podřízeným prvku UpdatePanel v aktuální jednotce zapouzdření.

<Referenční informace k elementu Triggers>

Potomci značek:

Tag Popis
<asp:AsyncPostBackTrigger> Určuje ovládací prvek a událost, která způsobí částečnou aktualizaci stránky pro UpdatePanel, který obsahuje tento odkaz na aktivační událost.
<asp:PostBackTrigger> Určuje ovládací prvek a událost, která způsobí aktualizaci celé stránky (aktualizaci celé stránky). Tuto značku lze použít k vynucení úplné aktualizace, když by ovládací prvek jinak aktivoval částečné vykreslování.

Návod: Triggery cross-UpdatePanel

  1. Vytvořte novou ASP.NET stránku s objektem ScriptManager nastaveným tak, aby bylo možné částečné vykreslování. Přidejte na tuto stránku dva prvky UpdatePanel – v první z nich obsahuje ovládací prvek Popisek ( Label1 ) a dva ovládací prvky Button ( Button1 a Button2 ). Tlačítko 1 by mělo mít na tlačítku Kliknutím aktualizovat obě a Tlačítko2 by mělo obsahovat text Kliknutím aktualizujete toto nebo něco podobného. Ve druhém prvku UpdatePanel zahrňte pouze ovládací prvek Label (Label2), ale nastavte jeho vlastnost ForeColor na jinou než výchozí, aby se odlišila.
  2. Vlastnost UpdateMode obou značek UpdatePanel nastavte na Conditional.

Výpis 1: Revize pro 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. V obslužné rutině události Click pro Button1 nastavte Label1.Text a Label2.Text na něco závislého na čase (například DateTime.Now.ToLongTimeString()). Pro obslužnou rutinu události Click pro Button2 nastavte pouze Label1.Text na hodnotu závislé na čase.

Výpis 2: Codebehind (oříznutý) v souboru 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. Stisknutím klávesy F5 sestavte a spusťte projekt. Všimněte si, že když kliknete na Aktualizovat oba panely, změní se text u obou popisků. Pokud však kliknete na Aktualizovat tento panel, aktualizuje se pouze Popisek1.

Snímek obrazovky, který zobrazuje první tlačítko s textem Aktualizovat oba panely a druhé tlačítko Aktualizovat tento panel

(Kliknutím zobrazíte obrázek v plné velikosti.)

Pod pokličkou

S využitím příkladu, který jsme právě vytvořili, můžeme se podívat na to, co ASP.NET AJAX dělá a jak fungují triggery mezi panely UpdatePanel. K tomu budeme pracovat s vygenerovaným zdrojovým HTML stránky, stejně jako s rozšířením Mozilla Firefox s názvem FireBug - s ním můžeme snadno prozkoumat postbacky AJAX. Použijeme také nástroj .NET Reflector od Lutz Roeder. Oba tyto nástroje jsou volně dostupné online a lze je najít pomocí vyhledávání na internetu.

Prozkoumání zdrojového kódu stránky nevysvědčí téměř nic neobvyklého; Ovládací prvky UpdatePanel se vykreslují jako <div> kontejnery a vidíme, že prostředek skriptu zahrnuje .<asp:ScriptManager> K dispozici jsou také některé nové specifické volání jazyka AJAX PageRequestManager, které jsou interní pro knihovnu skriptů AJAX klienta. Nakonec vidíme dva kontejnery UpdatePanel – jeden s vykreslenými <input> tlačítky se dvěma <asp:Label> ovládacími prvky vykreslenými jako <span> kontejnery. (Pokud v nástroji FireBug zkontrolujete strom modelu DOM, můžete si všimnout, že popisky jsou šedě, což značí, že neprodukují viditelný obsah.)

Klikněte na tlačítko Aktualizovat tento panel a všimněte si, že hlavní panel UpdatePanel se aktualizuje s aktuálním časem serveru. V nástroji FireBug zvolte kartu Konzola, abyste mohli žádost prozkoumat. Nejprve prozkoumejte parametry požadavku POST:

Snímek obrazovky s dialogovým oknem Firebug s vybranou konzolou

(Kliknutím zobrazíte obrázek v plné velikosti.)

Všimněte si, že UpdatePanel má na straně serveru kód AJAX přesně který řídicí strom byl aktivován prostřednictvím ScriptManager1 parametruUpdatePanel1: Button1 ovládacího prvku. Teď klikněte na tlačítko Aktualizovat oba panely. Pak při zkoumání odpovědi uvidíme řadu proměnných oddělených kanály nastavenou v řetězci; konkrétně vidíme, že horní UpdatePanel, UpdatePanel1, má celý svůj KÓD HTML odeslaný do prohlížeče. Knihovna klientských skriptů AJAX nahradí původní obsah HTML UpdatePanel novým obsahem prostřednictvím .innerHTML vlastnosti, a tak server odešle změněný obsah ze serveru jako HTML.

Teď klikněte na tlačítko Aktualizovat oba panely a prohlédněte si výsledky ze serveru. Výsledky jsou velmi podobné – oba elementy UpdatePanel obdrží ze serveru nový kód HTML. Stejně jako u předchozího zpětného volání se odešle další stav stránky.

Jak vidíme, protože k provedení zpětného odeslání AJAX není použit žádný speciální kód, je knihovna skriptů klienta AJAX schopna zachytit postbacky formulářů bez jakéhokoli dalšího kódu. Serverové ovládací prvky automaticky využívají JavaScript, aby automaticky neodesílaly formulář – ASP.NET automaticky vloží kód pro ověření formuláře a stav, kterého se dosahuje především automatickým zahrnutím prostředků skriptu, třídou PostBackOptions a třídou ClientScriptManager.

Zvažte například ovládací prvek CheckBox; prozkoumejte demontáž třídy v .NET Reflectoru. Chcete-li to provést, ujistěte se, že sestavení System.Web je otevřeno, a přejděte do System.Web.UI.WebControls.CheckBox třídy a otevřete metodu RenderInputTag . Vyhledejte podmínku, která kontroluje AutoPostBack vlastnost:

Snímek obrazovky znázorňující kód, který začíná na Kliknutím se rovná

(Kliknutím zobrazíte obrázek v plné velikosti.)

Pokud je u CheckBox ovládacího prvku povolena automatická zpětná vazba (prostřednictvím vlastnosti AutoPostBack je true), výsledná <input> značka se proto vykreslí pomocí skriptu ASP.NET zpracování událostí v jeho onclick atributu. Zachytávání odeslání formuláře pak umožňuje ASP.NET AJAX vložit do stránky neintrusivně, což pomáhá vyhnout se případným změnám způsobujícím chybu, ke kterým by mohlo dojít pomocí možná nepřesného nahrazení řetězce. Kromě toho to umožňuje jakýkoli vlastní ASP.NET ovládací prvek využívat sílu ASP.NET AJAX bez jakéhokoli dalšího kódu pro podporu jeho použití v rámci kontejneru UpdatePanel.

Funkce <triggers> odpovídá hodnotám inicializovaným ve volání PageRequestManager _updateControls (všimněte si, že knihovna klientských skriptů ASP.NET AJAX používá konvenci, že metody, události a názvy polí, které začínají podtržítkem, jsou označeny jako interní a nejsou určeny pro použití mimo samotnou knihovnu). S ním můžeme sledovat, které ovládací prvky jsou určeny k vyvolání zpětného volání AJAX.

Například přidáme na stránku dva další ovládací prvky, přičemž jeden ovládací prvek ponecháme zcela mimo UpdatePanels a jeden ponecháme uvnitř UpdatePanel. Přidáme ovládací prvek CheckBox v horní části UpdatePanel a vyřadíme DropDownList s několika barvami definovanými v seznamu. Tady je nový kód:

Výpis 3: Nové revize

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

A tady je nový kód na pozadí:

Výpis 4: Codebehind

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

Myšlenka této stránky je taková, že rozevírací seznam vybere jednu ze tří barev, aby se zobrazil druhý popisek, že zaškrtávací políčko určuje, jestli je tučné a jestli popisky zobrazují datum i čas. Zaškrtávací políčko by nemělo způsobit aktualizaci AJAX, ale rozevírací seznam by měl, i když není uložen v prvku UpdatePanel.

Snímek obrazovky, který zobrazuje webový prohlížeč s názvem Stránka bez názvu a rozevírací seznam s vybranou modrou barvou pod tlačítkem Aktualizovat oba panely

(Kliknutím zobrazíte obrázek v plné velikosti.)

Jak je vidět na výše uvedeném snímku obrazovky, poslední tlačítko, na které bylo možné kliknout, bylo pravé tlačítko Aktualizovat tento panel, které aktualizovalo horní čas nezávisle na dolním čase. Datum bylo také vypnuto mezi kliknutími, protože datum je vidět v dolním popisku. Nakonec je zajímavá barva dolního popisku: byla aktualizována nedávno než text popisku, což ukazuje, že stav ovládacího prvku je důležitý, a uživatelé očekávají, že se zachová prostřednictvím zpětného odeslání AJAX. Čas se ale neaktualizoval. Čas byl automaticky znovu vyplněn prostřednictvím trvalosti pole __VIEWSTATE stránky interpretované modulem runtime ASP.NET při opětovném vykreslení ovládacího prvku na serveru. Kód serveru ASP.NET AJAX nerozpozná, ve kterých metodách ovládací prvky mění stav; jednoduše znovu vyplní stav zobrazení a pak spustí události, které jsou vhodné.

Je však třeba poznamenat, že kdybych inicializoval čas v rámci Page_Load události, čas by se navýšil správně. V důsledku toho by vývojáři měli být opatrní, že se příslušný kód spouští během příslušných obslužných rutin událostí, a vyhnout se použití Page_Load, když je obslužná rutina události ovládacího prvku vhodná.

Souhrn

Ovládací prvek ASP.NET ROZŠÍŘENÍ AJAX UpdatePanel je univerzální a může využívat řadu metod pro identifikaci řídicích událostí, které by měly způsobit aktualizaci. Podporuje automatickou aktualizaci podřízenými ovládacími prvky, ale může také reagovat na události ovládacích prvků jinde na stránce.

Chcete-li snížit potenciál pro zpracování zatížení serveru, je doporučeno, aby ChildrenAsTriggers vlastnost UpdatePanel byla nastavena na falsehodnotu a aby události byly opted-in místo zahrnutí ve výchozím nastavení. Tím se také zabrání tomu, aby nepotřebné události způsobovaly potenciálně nežádoucí účinky, včetně ověření a změn vstupních polí. Tyto typy chyb může být obtížné izolovat, protože se stránka pro uživatele aktualizuje transparentně a příčina proto nemusí být okamžitě zřejmá.

Zkoumáním vnitřních funkcí modelu ASP.NET AJAX pro zachytávání formulářů jsme zjistili, že využívá architekturu, kterou již poskytuje ASP.NET. Přitom zachovává maximální kompatibilitu s ovládacími prvky navrženými pomocí stejné architektury a minimálně zasahuje do jakéhokoli dalšího JavaScriptu napsaného pro stránku.

Životopis

Rob Paveza je vedoucí vývojář aplikací .NET v Terraleveru (www.terralever.com), přední interaktivní marketingové firmě v Tempe v AZ. Je dostupný na adrese robpaveza@gmail.coma jeho blog se nachází na adrese http://geekswithblogs.net/robp/.

Scott Cate pracuje s webovými technologiemi microsoftu od roku 1997 a je prezidentem myKB.com (www.myKB.com), kde se specializuje na psaní ASP.NET aplikací zaměřených na softwarová řešení znalostní báze Knowledge Base. Scotta můžete kontaktovat e-mailem na adrese scott.cate@myKB.com nebo na jeho blogu na ScottCate.com