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

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

 

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

Google       Google       4. 9. 2009       17 579×

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.

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
Jakub studuje informatiku na FIT ČVUT, jeho oblíbenou platformou je .NET.
Web     Twitter     Facebook     LinkedIn    

Nové články

Obrázek ke článku Hybridní inteligentní systémy 2

Hybridní inteligentní systémy 2

V technické praxi využíváme často kombinaci různých disciplín umělé inteligence a klasických výpočtů. Takovým systémům říkáme hybridní systémy. V tomto článku se zmíním o určitém typu hybridního systému, který je užitečný ve velmi složitých výrobních procesech.

Obrázek ke článku Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Jak vést kvalitně tým v IT oboru: Naprogramujte si ty správné manažerské kvality

Vedení týmu v oboru informačních technologií se nijak zvlášť neliší od jiných oborů. Přesto však IT manažeři čelí výzvě v podobě velmi rychlého rozvoje a tím i rostoucími nároky na své lidi. Udržet pozornost, motivaci a efektivitu týmu vyžaduje opravdu pevné manažerské základy a zároveň otevřenost a flexibilitu pro stále nové výzvy.

Obrázek ke článku Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Síla týmů se na home office může vytrácet. Odborníci radí, jak z pracovních omezení vytěžit maximum

Za poslední rok se podoba práce zaměstnanců změnila k nepoznání. Především plošné zavedení home office, které mělo být zpočátku jen dočasným opatřením, je pro mnohé už více než rok každodenní realitou. Co ale dělat, když se při práci z domova ztrácí motivace, zaměstnanci přestávají komunikovat a dříve fungující tým se rozpadá na skupinu solitérů? Odborníci na personalistiku dali dohromady několik rad, jak udržet tým v chodu, i když pracovní podmínky nejsou ideální.

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