
ASP_NET_MVC_4_Framework_s_primerami_na_C_dlya_p
.pdf</div>
<div class="dataElem"> <label>Last Name</label>
@Html.TextBoxFor(m => m.LastName)
</div>
<input type="submit" value="Submit" />
}
Сгенерированный ими HTML ничем не отличается, но мы предпочитаем использовать строго типизированные вспомогательные методы потому, что они снижают риск возникновения ошибки изза опечатки в имени свойства.
Создаем элементы select
В таблице 19-7 показаны вспомогательные методы, которые используются для создания элементов select. С их помощью можно создать элемент, позволяющий выбрать один пункт из раскрывающегося списка, или элемент множественного выбора, который позволяет выбрать несколько пунктов. Как для других элементов форм, для этих вспомогательных методов существуют слабо и строго типизированные версии.
Таблица 19-7: Вспомогательные методы HTML, которые визуализируют элементы выбора
Элемент HTML |
Пример |
|
|
Html.DropDownList("myList", new SelectList(new [] {"A", "B"}), |
|
Раскрывающийся |
"Choose") Вывод: <select id="myList" name="myList"> <option |
|
список |
value="">Choose</option> <option>A</option> |
|
|
<option>B</option> </select> |
|
Раскрывающийся |
Html.DropDownListFor(x => x.Gender, new SelectList(new [] {"M", |
|
"F"})) Вывод: <select id="Gender" name="Gender"> <option>M</option> |
||
список |
||
<option>F</option> </select> |
||
|
||
Список |
Html.ListBox("myList", new MultiSelectList(new [] {"A", "B"})) Вывод: |
|
множественного |
<select id="myList" multiple="multiple" name="myList"> |
|
<option>A</option> |
||
выбора |
||
|
||
|
<option>B</option> </select> |
|
Список |
Html.ListBoxFor(x => x.Vals, new MultiSelectList(new [] {"A", "B"})) |
|
Вывод: <select id="Vals" multiple="multiple" name="Vals"> |
||
множественного |
||
<option>A</option> |
||
выбора |
||
|
||
|
<option>B</option> </select> |
Вспомогательные методы select принимают параметры SelectList или MultiSelectList. Разница между этими классами заключается в том, что для MultiSelectList есть опции конструктора, которые позволяют указать, что при первоначальной загрузке страницы необходимо выбрать более одного пункта.
Оба эти классы работают с последовательностью объектов IEnumerable. В таблице 19-7 мы создали внутренние массивы, которые содержат пункты списка, но SelectList и MultiSelectList будут извлекать значения для пунктов списка из объектов, в том числе из объекта модели. Как видите, мы создали элемент select для свойства Role модели Person в листинге 19 - 26.
502
Листинг 19-26: Создаем элемент select для свойства Person.Role
@model HelperMethods.Models.Person @{
ViewBag.Title = "CreatePerson";
}
<h2>CreatePerson</h2>
@using (Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post, new {@class = "personClass", data_formType = "person"}))
{
<div class="dataElem"> <label>PersonId</label> @Html.TextBoxFor(m => m.PersonId)
</div>
<div class="dataElem"> <label>First Name</label>
@Html.TextBoxFor(m => m.FirstName) </div>
<div class="dataElem"> <label>Last Name</label>
@Html.TextBoxFor(m => m.LastName) </div>
<div class="dataElem"> <label>Role</label>
@Html.DropDownListFor(m => m.Role,
new SelectList(Enum.GetNames(typeof (HelperMethods.Models.Role))))
</div>
<input type="submit" value="Submit" />
}
Мы определили свойство Role, используя значение из перечисления Role, определенного в том же классе. Поскольку объекты SelectList и MultiSelectList работают на объектах IEnumerable, мы должны применить метод Enum.GetNames, чтобы использовать Role enum в качестве источника для элемента select. В листинге 19-27 показан код HTML, который создает наше обновленное представление, в том числе элемент select.
Листинг 19-27: Код HTML, который создает представление CreatePerson
<!DOCTYPE html> <html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <title>CreatePerson</title>
<link href="/Content/Site.css" rel="stylesheet" /> <style type="text/css">
label {
display: inline-block; width: 100px;
}
.dataElem { margin: 5px;
}
</style>
</head>
<body>
<h2>CreatePerson</h2>
<form action="/app/forms/Home/CreatePerson" class="personClass" dataformtype="person"
method="post">
<div class="dataElem"> <label>PersonId</label>
503
<input data-val="true" data-val-number="The field PersonId must be a number." data-valrequired="
The PersonId field is required."
id="PersonId" name="PersonId" type="text" value="0" /> </div>
<div class="dataElem"> <label>First Name</label>
<input id="FirstName" name="FirstName" type="text" value="" /> </div>
<div class="dataElem"> <label>Last Name</label>
<input id="LastName" name="LastName" type="text" value="" /> </div>
<div class="dataElem"> <label>Role</label>
<select data-val="true" data-val-required="The Role field is required." id="Role" name="Role">
<option selected="selected">Admin</option> <option>User</option> <option>Guest</option>
</select>
</div>
<input type="submit" value="Submit" /> </form>
</body>
</html>
Резюме
В этой главе мы рассмотрели вспомогательные методы, которые можно использовать для создания блоков контента в представлениях. Мы показали вам, как создавать собственные внутренние и внешние вспомогательные методы, а затем рассмотрели встроенные вспомогательные методы, с помощью которых можно создавать элементы HTML form, input и select. В следующей главе мы продолжим рассматривать эту тему и научимся использовать шаблонные вспомогательные методы.
504
Шаблонные вспомогательные методы
Вспомогательные методы HTML, которые мы рассмотрели в предыдущей главе (такие как Html.CheckBoxFor и Html.TextBoxFor), генерируют определенный тип элемента. Это значит, что мы должны заранее решить, какой элемент будет представлять данное свойство модели, и вручную обновлять представления, если тип свойства изменится.
В этой главе мы рассмотрим шаблонные вспомогательные методы, которые позволяют нам только указать свойство, которое мы хотим визуализировать, не уточняя, какой элемент HTML для него требуется - это MVC Framework выяснит самостоятельно. Это более гибкий подход к отображению данных пользователю, хотя он и требует немного больше внимания и осторожности.
Обзор проекта для примера
В этой главе мы продолжим использовать проект HelperMethod, который создали в главе 19. Здесь у нас есть класс модели Person и пара сопровождающих типов. Чтобы легче было вспомнить, мы перечислили их в листинге 20-1.
Листинг 20-1: Типы Person, Address и Role
using System;
namespace HelperMethods.Models
{
public class Person
{
public int PersonId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } public Address HomeAddress { get; set; } public bool IsApproved { get; set; } public Role Role { get; set; }
}
public class Address
{
public string Line1 { get; set; } public string Line2 { get; set; } public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; }
}
public enum Role
{
Admin,
User,
Guest
}
}
Пример проекта содержит очень простой контроллер Home, с помощью которого мы отображаем формы и получаем данные от них. Определение класса HomeController показано в листинге 20-2.
505
Листинг 20-2: Класс HomeController
using System.Web.Mvc;
using HelperMethods.Models;
namespace HelperMethods.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Fruits = new string[] {"Apple", "Orange", "Pear"}; ViewBag.Cities = new string[] {"New York", "London", "Paris"}; string message = "This is an HTML element: <input>";
return View((object) message);
}
public ActionResult CreatePerson()
{
return View(new Person());
}
[HttpPost]
public ActionResult CreatePerson(Person person)
{
return View(person);
}
}
}
В этой главе мы будем использовать два метода действий CreatePerson, каждый из которых визуализирует представление /Views/Home/CreatePerson.cshtml. В листинге 20-3 показано представление CreatePerson, которое мы создали в конце главы 19.
Листинг 20-3: Представление CreatePerson
@model HelperMethods.Models.Person @{
ViewBag.Title = "CreatePerson";
Html.EnableClientValidation(false);
}
<h2>CreatePerson</h2>
@using (Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post, new {@class = "personClass", data_formType = "person"}))
{
<div class="dataElem"> <label>PersonId</label> @Html.TextBoxFor(m => m.PersonId)
</div>
<div class="dataElem"> <label>First Name</label>
@Html.TextBoxFor(m => m.FirstName) </div>
<div class="dataElem"> <label>Last Name</label>
@Html.TextBoxFor(m => m.LastName) </div>
<div class="dataElem"> <label>Role</label> @Html.DropDownListFor(m => m.Role,
new SelectList(Enum.GetNames(typeof (HelperMethods.Models.Role)))) </div>
<input type="submit" value="Submit" />
}
506
В него мы внесли одно изменение, которые выделено жирным шрифтом. По умолчанию, вспомогательные методы добавляют атрибуты data к HTML-элементам, таким образом обеспечивая валидацию форм, которую мы рассмотрели в главе 9 на примере приложения SportsStore. В этой главе мы не хотим их использовать, так что мы отключили их для представления CreatePerson с помощью метода Html.EnableClientValidation. Для остальной части приложения валидация на стороне клиента по-прежнему активирована. Подробно механизм валидации (в том числе и назначение data-атрибутов) мы рассмотрим в главе 23.
Использование шаблонных вспомогательных методов
Для начала мы рассмотрим шаблонные вспомогательные методы Html.Editor и Html.EditorFor. Метод Editor принимает аргумент string, определяющий свойство, для которого требуется элемент editor; он проводит поиск соответствующего свойства в ViewBag и объекте модели (данный процесс был описан в главе 18).
Метод EditorFor является его строго типизированным эквивалентом, в котором свойство модели, необходимое для элемента editor, указывается с помощью лямбда-выражения.
В листинге 20-4 показано, как вспомогательные методы Editor и EditorFor используются в представлении CreatePerson. Как мы уже упоминали в главе 19, мы предпочитаем использовать строго типизированные вспомогательные методы, так как они снижают риск возникновения ошибки из-за опечатки в имени свойства; в этом листинге мы использовали оба типа, просто чтобы показать, что вы можете смешивать и сочетать методы так, как считаете нужным.
Листинг 20-4: Используем методы Editor и EditorFor
@model HelperMethods.Models.Person @{
ViewBag.Title = "CreatePerson"; Html.EnableClientValidation(false);
}
<h2>CreatePerson</h2>
@using (Html.BeginRouteForm("FormRoute", new {}, FormMethod.Post, new {@class = "personClass", data_formType = "person"}))
{
<div class="dataElem"> <label>PersonId</label>
@Html.Editor("PersonId")
</div>
<div class="dataElem"> <label>First Name</label>
@Html.Editor("FirstName")
</div>
<div class="dataElem"> <label>Last Name</label>
@Html.EditorFor(m => m.LastName)
</div>
<div class="dataElem"> <label>Role</label>
@Html.EditorFor(m => m.Role)
</div>
<div class="dataElem"> <label>Birth Date</label>
@Html.EditorFor(m => m.BirthDate)
</div>
<input type="submit" value="Submit" />
507

}
Editor и EditorFor создают идентичные элементы HTML; единственное различие между ними – это способ записи свойства, для которого создаются элементы editor. Вы можете увидеть результат применения этих методов, запустив приложение и перейдя по ссылке Home/CreatePerson, как показано на рисунке 20-1.
Рисунок 20-1: Используем методы Editor и EditorFor в форме
Не считая свойства BirthDate, эта форма по виду не отличается от формы, которую мы создали в главе 19. Тем не менее, изменения в ней довольно существенные; их можно увидеть, открыв страницу в другом браузере. На рисунке 20-2 показана та же страница в браузере Opera (www.opera.com).
Рисунок 20-2: Отображение формы, созданной с помощью вспомогательных методов Editor и EditorFor
508
Обратите внимание, что элементы для свойств PersonId и BirthDate выглядят по-другому. У элемента PersonId появились стрелки (которые позволяют увеличивать и уменьшать значение) а элемент BirthDate теперь позволяет выбрать дату.
В спецификации HTML5 определены различные типы элементов input, которые используются для редактирования общих типов данных, таких как числа и даты. Методы Editor и EditorFor выбирают один из этих новых типов, основываясь на типе свойства, которое мы хотим отредактировать. В листинге 20-5 показан код HTML, который был создан для формы на рисунках
20-1 и 20-2.
Листинг 20-5: Элементы HTML input, созданные вспомогательными методами Editor и EditorFor
<!DOCTYPE html> <html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <title>CreatePerson</title>
<link href="/Content/Site.css" rel="stylesheet" /> <style type="text/css">
label {
display: inline-block; width: 100px;
}
.dataElem { margin: 5px;
}
</style>
</head>
<body>
<h2>CreatePerson</h2>
<form action="/app/forms/Home/CreatePerson" class="personClass" data-formtype="person" method="post">
<div class="dataElem"> <label>PersonId</label>
<input class="text-box single-line" id="PersonId" name="PersonId" type="number" value="0" />
</div>
<div class="dataElem"> <label>First Name</label>
<input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="" />
</div>
<div class="dataElem"> <label>Last Name</label>
<input class="text-box single-line" id="LastName" name="LastName" type="text" value="" />
</div>
<div class="dataElem"> <label>Role</label>
<input class="text-box single-line" id="Role" name="Role" type="text" value="Admin" />
</div>
<div class="dataElem"> <label>Birth Date</label>
<input class="text-box single-line" id="BirthDate" name="BirthDate" type="datetime" value="01/01/0001 00:00:00" />
</div>
<input type="submit" value="Submit" /> </form>
</body>
</html>
509
