Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Tip na přehlednější šablony

09.25 - 12. července 2009 | ASP.NET 2.0

Zastávám názor, že šablona by měla být co nejvíce přehledná a obsahovat co nejméně programového kódu. Pojďme se podívat na některé kousky zasmrádlého kódu a jak se s nimi vypořádat.

Html.ActionLink je pro mne jedním z prvních míst, kde zvednout ukazováček a říct: „takhle ne.“ Již ve spotu o routingu jsem psal, že procházení routovací tabulky při hledání akce je výpočetně náročné a pokud vaše tabulka obsahuje mnoho řádků, může být zdrojem nepříjemného zdržení. Mějme například helper odkaz na detail zboží v jehož URL obsahuje informace o kategorii zboží, jeho id a název:

<%= Html.ActionLink(Model.Name, "Detail", "Goods", new { id = Model.Id, name = Model.UrlName, category = Model.Category.UrlName }) %>

Tohle rozhodně není přehledné, ani výkonné. Začněme tedy refaktorovat. Nelíbí se mi, že tag odkazu je generovaný a že pořádně netuším, jestli třeba nejsou parametry ve špatném pořadí. A co potom takový kodér? Co když bude chtít přidat nějakou třídu, aby mohl tento konkrétní odkaz lépe nastylovat nebo mu dát nějaký sémantický význam? Přejděme na Url.Action!

<a href="<%= Url.Action("Detail", "Goods", new { id = Model.Id, name = Model.UrlName, category = Model.Category.UrlName }) %>"><%= Html.Encode(Model.Name) %></a>

No moc jsme si nepomohli. Sice teď máme větší kontrolu nad generovaným kódem, ale kód je o dost delší a pořád pěkně „smrdí.“ Zbavme se teď kouzelných řetězců, ty mohou být zdrojem špatně dohledatelných chyb!

<a href="<%= Url.RouteUrl(RouteTo.CommodityDetail, new { id = Model.Id, name = Model.UrlName, category = Model.Category.UrlName }) %>"><%= Html.Encode(Model.Name) %></a>

Zbavili jsme se možnosti udělat chybu v názvu akce nebo řadiče a navíc teď probíhá vyhledávání routy v tabulce podle klíče, tudíž mnohem efektivněji. Ale pořád mi tu něco smrdí. Ano je to ta anonymní třída, i tady je velká šance na vnesení chyby. Ačkoli to tak na první pohled nevypadá, názvy vlastností této třídy nejsou nic jiného než kouzelné řetězce, jen bez uvozovek. Na pozadí se totiž překládají jako klíče ve slovníku. Lék na to je jednoduchý. Vytvoříme si vlastní helper!

<a href="<%= Url.CommodityDetail(Model) %>"><%= Html.Encode(Model.Name) %></a>

Zápis se rázem zpřehlednil, snížila se možnost zanesení chyby a množství opakovaného kódu.

Autor: Aleš Roubíček | Přidej komentář | Delicious | Digg | FriendFeed | Facebook | Linkuj! | Jagg

Komentáře RSS

  1.  

    Augi

    14.13 - 12. července 2009 | #

    Další možností na zpřehlednění zápisu je použití generické metody ActionLink z Microsoft.Web­.Mvc, ale tam je výkonnost ještě mnohem horší. Autoři o tomhle problému vědí a mám pocit, že jsem na blogu Phila Haacka četl, že v další verzi ASP.NET MVC by měli být T4 šablony, které budou generovat helpery na generování odkazů. IMHO se dají najít na netu už teď.

  2.  

    Aleš Roubíček

    15.18 - 12. července 2009 | #

    [1] Augi: Generický ActionLink, snižije riziko kouzelných řetězců, ale rozhodně nenapomáhá k větší přehlednosti kódu (Generické parametry a lambda výrazy do šablony nepatří).

    T4MVC ale stále generuje action linky, takže pořád žádná sláva. Ukázané řešení vyžaduje trchu víc práce, než automaticé generování kódu, ale je, myslím, použitelnější. Metoda s jedním parametrem a vhodně zvoleným názvem je prostě lepší. :)

  3.  

    Augi

    13.04 - 29. července 2009 | #

    [2] Aleš Roubíček:No já právě myslím, že ty T4MVC by měly ve finále umět generovat oboje – extension metody pro Html i Url helper. A pokud tomu tak nebude, tak nebude problém si to přiohnout :) Každopádně souhlasím, že cílem by mělo být to, co ukazuješ jako poslední…

  4.  

    optik

    11.17 - 11. srpna 2009 | #

    Chápu správně, že pro každé routerem generované url se pak musí psát vlastní helper? To bych řekl, že není moc dobré, pokud tedy třeba ty helpery nejdou generovat. To předposlední bych pak viděl jako dostatečný kompromis.

  5.  

    Aleš Roubíček

    12.56 - 11. srpna 2009 | #

    [4] optik: Já jedním helperem vygeneruju stovky URL. ;)

    U jednoduchých rout si vystačíš s Url.RouteUrl(RouteTo.HomePage), ukazované řešení je vhodné tam, kde už bys musel zadávat parametry. BTW vytvořit takový helper je celkem snadné. Jednou napíšu, co chci generovat, zkopíruju, udělám z toho extenzi a je to, max minuta práce.

  6.  

    optik

    19.06 - 11. srpna 2009 | #

    [5] Aleš Roubíček: Jasné, že jen pro pro parametrické routy, ale i tak, tam kde je více jak dejme tomu 10 různých url, už mě to přijde jako dost práce navíc.

    Dál si myslím, že pokud je používání obecných parametrických url helperů opravdu nevhodné, tak by prostě vůbec neměly být součástí knihoven a příklady a návody by měly doporučovat psaní konkrétních helperů. Jsou nějaké příklady, kde je jejich použití vhodné? Pokud ano, chtělo by je to alespoň okrajově zmínit v článku.

  7.  

    Aleš Roubíček

    20.32 - 11. srpna 2009 | #

    [6] optik: článek shrnuje pouze mé vlastní zkušenosti, co funguje na projektu, na kterém dělám.

    Rozhodně je mohem větší práce, když přidáš do routy další parametr a musíš dohledávát ve všech šablonách, kde se routa generuje, a všude přidat parametr. Takhle přidám ten parametr jen na jednom místě a je to. To je hlavní výhoda, pak taky zmenšení C# kódu z všabloně.

  8.  

    Augi

    09.04 - 12. srpna 2009 | #

    optik: K Tvému prvnímu příspěvku – jdou generovat ;)

Místo pro tvůj názor

Povinné je jméno a komentář, z e-mailu se rozpoznají Gravatary.
Komentář je formátován pomocí Texy! syntaxu.
Například: **tučný text**, *kurzíva*, "text odkazu":adresa.
Internetové adresy jsou převáděny na odkazy.
Na komentáře se můžete odkazovat pomocí [číslo komentáře].

Nový komentář