| Пятница, 22 марта, 2013
Метки: ASP.NET MVC Комментарии: 0
Иногда работа c выпадающими списками вызывает некоторые затруднения. Рассмотрим пример, в котором нам нужно создать страницу редактирования музыкального трека. Каждая композиция содержится в каком либо альбоме, имеет название и номер. Это можно изобразить в следующем коде:
@Html.DropDownList("AlbumId", Model.Albums) ... @Html.TextBox("Title", Model.Title) ... @Html.TextBox("TrackNumber", Model.TrackNumber)
Вспомогательный метод Html.DropDownList работает с объектами SelectListItem. Модель представления можно представить так:
public class EditSongViewModel { public string Title { get; set; } public int TrackNumber { get; set; } public IEnumerableAlbums { get; set; } }
Некоторым разработчикам не нравится использовать типы SelectListItem в моделях представления и вместо этого они конвертируют элементы коллекции в SelectListItem прямо в представлении. Но на самом очень предпочтительно использовать SelectListItem в модели представления, так как модель должна упрощать код в самих представлениях.
Существует несколько способов для создания последовательностей объектов SelectListItem. Наиболее подходящим может быть создание метода расширения для последовательности (в нашем случае – объекты Album), в котором коллекция сущностей конвертируется в коллекцию объектов SelectListItem.
public static IEnumerableToSelectListItems(this IEnumerable albums, int selectedId) { return albums.OrderBy(album => album.Name) .Select(album => new SelectListItem { Selected = (album.ID == selectedId), Text = album.Name, Value = album.ID.ToString() }); }
Этот метод можно использользовать так:
model.Albums = _repository.FindAllAlbums().ToSelectItems(selectedId);
Этот код работает, потому что Html.DropDownList принимает в качестве входного параметра IEnumerable
Можно использовать класс SelectList, но применять его нужно аккуратно. Например, если в SelectList не указать параметры DataTextField и DataValueField, то выпадающий список не будет работать корректно.
// неправильное использование model.Albums = new SelectList( _repository.FindAllAlbums().ToSelectListItems(1) );
Выпадающий список отобразит “System.Web.Mvc.SelectListItem” вместо текстового имени каждого элемента.
Класс SelectList разработан для преобразования элементов, с той же целью, что и наш метод расширения выше (для преобразования элементов в коллекцию SelectListItem), но тут используется позднее связывание. Следующий код будет работать, так как мы указали поля описаний и значений для елементов списка.
// правильное использование model.Albums = new SelectList( _repository.FindAllAlbums(), "ID", "Name" );
Если для принятия данных формы страницы используется та же сама модель представления, то можно предположить, что стандартный привязчик значений ASP.NET MVC проинициализирует снова коллекцию альбомов и укажет выбранный. Но , к сожалению, это не так - коллекция альбомов будет пустой.
Серверу страница вышлет только идентификатор выбранного альбома. Если нужно получить это значение в модели, то необходимо добавить свойство AlbumID.
public class EditSongViewModel { public int AlbumId { get; set; } public string Title { get; set; } public int TrackNumber { get; set; } public IEnumerable<SelectListItem> Albums { get; set; } }И дополнительно код в представлении можно изменить так:
@Html.DropDownListFor(x => x.AlbumId, Model.Albums) ... @Html.TextBoxFor(x => x.Title) ... @Html.TextBoxFor(x => x.TrackNumber)
Итак, резюмируем главные моменты вышеизложенного:
Copyright © CodeHint.ru 2013-2024 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля