ASP.NET MVC v praxi od A do Z, 8. díl – Třídy ViewData a ViewModel
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

ASP.NET MVC v praxi od A do Z, 8. díl – Třídy ViewData a ViewModelASP.NET MVC v praxi od A do Z, 8. díl – Třídy ViewData a ViewModel

 
Hledat
Moderní platforma pro vytvoření vašeho nového webu – Wix.com.
Nyní už můžete mít web zdarma.
Vybavení pro Laser Game
Spuštěn Filmový magazín
Laser Game Brno

ASP.NET MVC v praxi od A do Z, 8. díl – Třídy ViewData a ViewModel

Google       Google       4. 9. 2009       13 732×

Dnes to bude pro změnu krátké, probereme dva způsoby, jak předávat data z controlleru příslušným views, a to pomocí tříd ViewData a ViewModel.

Reklama
Reklama

Pomocí těchto tříd můžeme poskytnout bohatší uživatelské rozhraní. Hezké by třeba bylo, kdyby měly stránky pro přidání a upravení večeře místo TextBoxu DropDownList (rozbalovací menu) pro vybrání země. Ale ne že bychom museli do DropDownListu dostupné země natvrdo napsat, musely by se pěkně dynamicky načítat podle toho, pro které státy máme dostupné validace telefonních čísel. Pomocí tříd ViewData a ViewModel nebude těžké toho dosáhnout.

Použití třídy ViewData

Bázová třída Controller, od které je odvozen každý controller, poskytuje vlastnost ViewData, do které můžeme uložit další data, která chceme předat view. Když budeme chtít, aby se seznam zemí zobrazoval jako vysouvací menu, můžeme do ViewData uložit instanci třídy SelectList:

// GET: /Dinners/Edit/2
public ActionResult Edit(int id)
{
    Dinner dinner = dinnerRepository.GetDinner(id);

    ViewData["Countries"] = new SelectList(PhoneValidator.Countries, dinner.Country);

    return View(dinner);
}

Konstruktor SelectListu přijímá v prvním parametru seznam hodnot pro DropDownList a jako druhý parametr přijímá defaultně zvolenou hodnotu. Řádek s TextBoxem pro výběr země v šabloně Edit pak stačí jen přepsat, aby vypadal následovně:

<label for="Country">Země:</label>
<%= Html.DropDownList("Country", ViewData["Countries"] as SelectList) %>             
<%=Html.ValidationMessage("Country", "*") %>

I metoda Html.DropDownList přijímá dva parametry – první určuje název ovládacího prvku a druhý parametr je seznam hodnot. Když teď aplikaci spustíme a zadáme URL „/Dinners/Edit/1“ uvidíme to, co je na obrázku:

Protože země chceme vybírat i v případě chyb na stránce s úpravami, musíme patřičně upravit i POST verzi metody Edit:

// POST: /Dinners/Edit/2
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues)
{
    Dinner dinner = dinnerRepository.GetDinner(id);
    try
    {
        UpdateModel(dinner);
        dinnerRepository.Save();

        return RedirectToAction("Details", new {id = dinner.DinnerID});
    }
    catch
    {
        ModelState.AddRuleViolations(dinner.GetRuleViolations());
        ViewData["Countries"] = new SelectList(PhoneValidator.Countries, dinner.Country);

        return View(dinner);
    }
}

Pokud se vám zdá, že jsem zapomněl na metodu Create, protože při vytváření večeří přece taky chceme vybírat zemi, kde se večeře pořádá, máte pravdu. To totiž uděláme pomocí třídy ViewModel, abychom viděli oba způsoby v akci.

Použití třídy ViewModel

Použití ViewData, které jsme si ukázali v předchozí kapitole, má výhodu v tom, že je poměrně rychlé a jednoduché na implementaci. Někdo ale používá tento způsob nerad, protože při psaní názvu klíče může dojít k překlepu, který ale při kompilaci nijak nezjistíme (teď mluvím o té části ve hranatých závorkách).

Alternativním postupem je použití třídy ViewModel. Funguje to tak, že vytvoříme třídu, která má všechny potřebné vlastnosti, a teprve tu předáme danému view. Ukážeme si kód a vzápětí vysvětlím, jak to funguje (pro následující kód vytvořte třídu DinnerFormViewModel v adresáři Controllers):

using System.Web.Mvc;
using NerdDinner.Models;

namespace NerdDinner.Controllers
{
    public class DinnerFormViewModel
    {
        // vlastnosti
        public Dinner Dinner { get; private set; }
        public SelectList Countries { get; private set; }

        // konstruktor
        public DinnerFormViewModel(Dinner dinner)
        {
            Dinner = dinner;
            Countries = new SelectList(PhoneValidator.Countries, dinner.Country);
        }
    }
}

Takže teď k tomu, jak to vlastně bude fungovat. Normálně předáváme view instanci třídy Dinner. Jak ale vidíte, tak konstruktor třídy DinnerFormViewModel přijímá jako parametr také Dinner objekt a pak ho ukládá do vlastnosti, dá se tedy říct, že tato třída obaluje jak Dinner objekt, tak i SelectList naplněný seznamem dostupných zemí. Pak stačí jen mírně upravit akční metodu:

// GET: /Dinners/Edit/2
public ActionResult Edit(int id)
{
    Dinner dinner = dinnerRepository.GetDinner(id);

    return View(new DinnerFormViewModel(dinner));
}

Ještě musíme provést pár úprav šablony Edit. Nejdříve ji nastavíme tak, aby očekávala DinnerFormViewModel objekt, namísto stávajícího Dinner objektu (podívejte na tag „Page“ v kódu níže). K tomu navíc musíme upravit všechny položky ve formuláři, protože hodnoty jsou od teď dostupné přes Model.Dinner.NazevVlastnosti, nikoliv Model.NazevVlastnosti jako předtím. Kód níže ukazuje všechny změny, včetně upravené definice DropDownListu:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Controllers.DinnerFormViewModel>" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Upravit: <%=Html.Encode(Model.Dinner.Title)%>
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Upravit večeři</h2>

    <%=Html.ValidationSummary("Opravte prosím všechny chyby a zkuste to znovu.") %>  
    
    <% using (Html.BeginForm()) { %>

        <fieldset>
            <p>
                <label for="Title">Název večeře:</label>
                <%=Html.TextBox("Title", Model.Dinner.Title) %>
                <%=Html.ValidationMessage("Title", "*") %>
            </p>
            <p>
                <label for="EventDate">Datum:</label>
                <%=Html.TextBox("EventDate", String.Format("{0:g}", Model.Dinner.EventDate))%>
                <%=Html.ValidationMessage("EventDate", "*") %>
            </p>
            <p>
                <label for="Description">Popis:</label>
                <%=Html.TextArea("Description", Model.Dinner.Description) %>
                <%=Html.ValidationMessage("Description", "*")%>
            </p>
            <p>
                <label for="Address">Adresa:</label>
                <%=Html.TextBox("Address", Model.Dinner.Address) %>
                <%=Html.ValidationMessage("Address", "*") %>
            </p>
            <p>
                <label for="Country">Země:</label>
                <%= Html.DropDownList("Country", Model.Countries) %>             
                <%=Html.ValidationMessage("Country", "*") %>
            </p>
            <p>
                <label for="ContactPhone">Telefon:</label>
                <%=Html.TextBox("ContactPhone", Model.Dinner.ContactPhone) %>
                <%=Html.ValidationMessage("ContactPhone", "*") %>
            </p>
            <p>
                <label for="Latitude">Zem. šířka:</label>
                <%=Html.TextBox("Latitude", Model.Dinner.Latitude) %>
                <%=Html.ValidationMessage("Latitude", "*") %>
            </p>
            <p>
                <label for="Longitude">Zem. délka:</label>
                <%=Html.TextBox("Longitude", Model.Dinner.Longitude) %>
                <%=Html.ValidationMessage("Longitude", "*") %>
            </p>
            <p>
                <input type="submit" value="Uložit"/>
            </p>
        </fieldset>
        
    <% } %>
    
</asp:Content>

Upravenou POST Edit metodu a Create metody nemá vůbec cenu ukazovat. Jediná změna v nich totiž je přepsané „return“ tak, aby vypadalo takto:

return View(new DinnerFormViewModel(dinner));

Bohužel musíme upravit i Create view, aby vše fungovalo jako doposud – změny uvidíte v následujícím zdrojovém kódu:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Controllers.DinnerFormViewModel>" %>

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
     Vytvořit večeři
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Vytvořit večeři</h2>

    <%=Html.ValidationSummary("Opravte prosím všechny chyby a zkuste to znovu.") %>
 
    <% using (Html.BeginForm()) {%>
  
        <fieldset>
            <p>
                <label for="Title">Název:</label>
                <%= Html.TextBox("Title", Model.Dinner.Title) %>
                <%= Html.ValidationMessage("Title", "*") %>
            </p>
            <p>
                <label for="EventDate">Datum:</label>
                <%=Html.TextBox("EventDate", Model.Dinner.EventDate) %>
                <%=Html.ValidationMessage("EventDate", "*") %>
            </p>
            <p>
                <label for="Description">Popis:</label>
                <%=Html.TextArea("Description", Model.Dinner.Description) %>
                <%=Html.ValidationMessage("Description", "*") %>
            </p>
            <p>
                <label for="Address">Adresa:</label>
                <%=Html.TextBox("Address", Model.Dinner.Address) %>
                <%=Html.ValidationMessage("Address", "*") %>
            </p>
            <p>
                <label for="Country">Země:</label>
                <%= Html.DropDownList("Country", Model.Countries) %> 
                <%=Html.ValidationMessage("Country", "*") %>
            </p>
            <p>
                <label for="ContactPhone">Telefon:</label>
                <%=Html.TextBox("ContactPhone", Model.Dinner.ContactPhone) %>
                <%=Html.ValidationMessage("ContactPhone", "*") %>
            </p>            
            <p>
                <label for="Latitude">Zem. šířka:</label>
                <%=Html.TextBox("Latitude", Model.Dinner.Latitude) %>
                <%=Html.ValidationMessage("Latitude", "*") %>
            </p>
            <p>
                <label for="Longitude">Zem. délka:</label>
                <%=Html.TextBox("Longitude", Model.Dinner.Longitude) %>
                <%=Html.ValidationMessage("Longitude", "*") %>
            </p>
            <p>
                <input type="submit" value="Uložit"/>
            </p>
        </fieldset>
    <% } 
%>
</asp:Content>

Odměnou za naše snažení nám bude DropDownList i na stránce s vytvářením večeří:

Dnešní kus práce máme za sebou. Všimli jste si ale, jak si jsou view šablony Edit a Create hrozně podobné? Přece by s tím mělo jít něco udělat, a taky že jde. Proto budou naším příštím tématem „partial“ šablony a master pages, které jistě znáte z klasického ASP.NET.

Zdroj: http://nerddinnerbook.s3.amazonaws.com/Part6.htm

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
(fotka) Jakub KottnauerJakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Pracujete u počítače ve stoje? Dbejte na správné držení těla

Pracujete u počítače ve stoje? Dbejte na správné držení těla

Práce ve stoje je jedna z variant, jak změnit polohu těla při dlouhodobé práci u počítače. Především je důležité nezapomínat na správné držení těla, abychom při práci nenamáhali naší krční páteř. Primářka MUDr. Michaela Tomanová představí hlavní bonusy a rizika práce u počítače ve stoje.

Reklama
Reklama
Obrázek ke článku Firmy musejí s nástupem Průmyslu 4.0 více dbát na kyberbezpečnost. V ohrožení je i jejich know-how.

Firmy musejí s nástupem Průmyslu 4.0 více dbát na kyberbezpečnost. V ohrožení je i jejich know-how.

Destabilizace firmy či ukradené know-how. To jsou možná hlavní budoucí rizika spojená s nedostatečnou kybernetickou bezpečností průmyslových firem, na která upozorňují experti. Vzhledem k postupující digitalizaci výrobních či technologických procesů a přechodu k takzvanému Průmyslu 4.0 může těchto hrozeb postupně přibývat. Varují před nimi i nejnovější průzkumy. 

Obrázek ke článku Nový CEBIT je připraven: Pochopit digitální dnešek a objevit digitální zítřek

Nový CEBIT je připraven: Pochopit digitální dnešek a objevit digitální zítřek

Nový veletrh  CEBIT je připraven. V polovině června začne v Hannoveru evropský festival obchodu s radikálně změněnou koncepcí věnovaný inovacím a digitalizaci.  CEBIT jedinečnou formou spojuje obchod v digitálním hospodářství 
s festivalovými prvky a posouvá do středu pozornosti téma digitální transformace hospodářství a společnosti.  

Obrázek ke článku Black Swan Security Congress ukáže, jak se chránit před největšími hrozbami na internetu

Black Swan Security Congress ukáže, jak se chránit před největšími hrozbami na internetu

Dva dny plné přednášek a diskusí na téma často podceňovaných bezpečnostních rizik na internetu pořádá Paralelní polis v pražských Holešovicích. Akce s názvem Black Swan Security Congress bude od pátku 18. do soboty 19. května hostit etické hackery a experty na IT bezpečnost převážně z Česka a Slovenska. Ti účastníkům vysvětlí, jaká rizika nese fenomén „černé labutě a jak se před ním mohou chránit.

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032018 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý