Pozor na dynamické vytváření komponent ve fázi Load

Tomáš Herceg       06.04.2011       ASP.NET/IIS       10925 zobrazení

Pokud v ASP.NET píšete vlastní komponenty, je vhodné si rozmyslet, ve které fázi životního cyklu je do stránky chcete přidat. Obecně platí, že pokud k vytvoření stromu komponent nepotřebujete informace z ViewState (komponenta má vždy pevnou vnitřní strukturu, např. odkaz a obrázek), můžete je vytvořit již ve fázi Init. V tuto totiž data z ViewState ani z formulářových prvků nejsou načtena.

Některé složitější komponenty, jako třeba Repeater, ale k vytvoření komponent potřebují informace, které se drží ve ViewState nebo ve formulářových polích. Při prvním požadavku (GET) si Repeater provede databinding, tedy podle počtu položek zopakuje šablonu, nastaví komponentám některé vlastnosti, a tyto nastavené vlastnosti se uloží do ViewState. Dál si Repeater potřebuje zapamatovat počet položek, které v něm byly.

Při postbacku pak jen zjistí, kolik položek měl minule, a zopakuje příslušnou šablonu. To ale musí dělat až ve chvíli, kdy má ViewState, protože právě tam má uloženo, kolik položek měl minule. V takovém případě musí komponenty vytvářet a přidávat do stránky až ve fázi Load.

Typická otázka je, co se stane, když komponentu přidáme až ve chvíli, kdy už jsou ViewState a formulářová data načtena. Neztratí se? V mnoha článcích se dočtete, že ne, že se automaticky donačtou při přidání do kolekce Controls a že korektně proběhnou všechny předchozí fáze životního cyklu stránky.

To však není úplně přesné, už dávno jsem psal o tom, že když komponenty přidáte až moc pozdě (ve fázi PreRender), tak se sice ViewState načte, ale formulářová data už ne.

Dnes jsem zjistil ještě jednu věc – pokud komponenty přidáte ve fázi Load, tak se sice zavolá metoda LoadPostData, která v komponentě obnoví stav podle formulářových dat (například TextBoxu nastaví hodnotu Text na to, co uživatel do formuláře zadal), ale nezavolá se hned, tedy něhem volání Controls.Add. Zavolá se až po ukončení fáze Load (před tím, než se vyvolávají akční a změnové události komponent).

Takže pokud v komponentě v metodě OnLoad vytvoříte dynamické komponenty a hned k nim přistupujete, nedivte se, že nemají ještě načtená formulářová data (jestli mají ViewState jsem nezkoušel, protože komponenta, kterou píšu, ho má vypnutý). To je trochu problém, pokud s těmi daty chcete pracovat ještě před vyvoláním akčních a změnových událostí komponent – nemáte totiž metodu, kterou overridovat.

Mezi OnLoad a vyvoláváním akčních událostí už nic není, tedy alespoň jsem nic nenašel.

 

hodnocení článku

2 bodů / 2 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Diskuse: Pozor na dynamické vytváření komponent ve fázi Load

Doplnil bych, že když pro vytvoření komponenty potřebujete pouze ViewState a ne formulářová data, tak stačí komponenty přidat v CreateChildControls a v OnLoad už mají načtená formulářová data.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To není tak úplně pravda, záleží, kdy se CreateChildControls volá (což záleží na tom, ze které třídy dědíte, a jak tu komponentu používáte).

Rozhodně se nemůžete spolehnout na to, že v době volání CreateChildControls bude k dispozici ViewState. Některé komponenty už v Init fázi volají EnsureChildControls a máte problém, pokud ViewState potřebujete už při vytváření komponent (třeba Repeater musí vědět, kolikrát má vnitřní šablonu zopakovat, a to má uložené ve ViewState).

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback