Через общий репозиторий можно создавать как DropDown
, так и MultiSelect
списки.
Я уже ответил на свой вопрос о DropDowns
, поэтому не буду повторяться.
Список MultiSelect
использует тот же метод для пустого списка, но вам нужно что-то еще, если вы хотите редактировать список, отображая текущие выборки (как и в приведенной выше ссылке, я использую chosen.js для отображения поля ввода MultiSelect
).
Модели
Существует ViewModel для MultiSelectList
, которую я вызываю из основной ViewModel. Проверка проводится в отдельном файле.
MultiSelect ViewModel
public class MultiSelectViewModel
{
public MultiSelectList Items { get; set; }
}
Entity ViewModel
public partial class InterventionTypeEditViewModel
{
public int interventionTypeID { get; set; }
public string interventionType { get; set; }
public MultiSelectViewModel outcomeID { get; set; }
}
Проверка
[MetadataTypeAttribute(typeof(InterventionTypeEditViewModelMetaData))]
public partial class InterventionTypeEditViewModel
{
}
public class InterventionTypeEditViewModelMetaData
{
[Key]
[ScaffoldColumn(false)]
[HiddenInput(DisplayValue = false)]
public int interventionTypeID { get; set; }
[Required]
[Display(Name = "Intervention Type")]
public string interventionType { get; set; }
[Display(Name = "Outcome")]
[UIHint("_multiEdit")]
public string outcomeID { get; set; }
}
Шаблон редактора
[UIHint("_multiEdit")]
указывает на следующий шаблон редактора. Атрибуты класса предназначены для chosen.js и файла Twitter Bootstrap.
@model WhatWorks.ViewModels.MultiSelectViewModel
@Html.DropDownList("", Model.Items, null, new { @class = "chosen input-xxlarge", multiple = "multiple", })
Контроллер
В контроллере я дважды вызываю репозиторий — один раз для объекта-владельца контроллера (в данном случае tInterventionType
) и один раз для объекта, который будет предоставлять наши значения MultiSelectList
(tOutcome
). Экземпляр _repo
относится к параметру универсального типа T в стандартных универсальных методах CRUD, Get и GetById. Экземпляр _multi использует параметр универсального типа O, чтобы различать сущность в репозитории. Это может быть не лучшая практика (советы приветствуются), но это работает.
private readonly IAdminRepository<tInterventionType> _repo;
private readonly IAdminRepository<tOutcome> _multi;
public InterventionTypeController(IAdminRepository<tInterventionType> _repo,
IAdminRepository<tOutcome> _multi)
{
this._repo = _repo;
this._multi = _multi;
}
Затем в запросе GET
для действия Edit
selectFrom
возвращает все элементы для списка выбора, а currentSelect
возвращает уже выбранные элементы. Затем MultiSelectViewModel
заполняется с помощью этого MultiSelectList
конструктора.< /а>
// GET: /InterventionType/Edit/5
public ActionResult Edit(int id = 0)
{
var selectFrom = _multi.Get();
IEnumerable<int> currentSelect = from o in selectFrom
where o.tInterventionType.Any(m => m.interventionTypeID == id)
select o.outcomeID;
MultiSelectViewModel outcome = new MultiSelectViewModel
{
Items = new MultiSelectList(selectFrom, "outcomeID", "outcome", currentSelect)
};
InterventionTypeEditViewModel a = GetUpdate(id);
a.outcomeID = outcome;
if (a == null)
{
return HttpNotFound();
}
return View(a);
}
Репозиторий
Метод в репозитории такой же, как стандартный Get()
, но параметр универсального типа O относится к передаваемой модели.
public IEnumerable<O> GetMultiSelectEntity<O>()
where O : class
{
return context.Set<O>().ToList();
}
Вид
Как и в случае стандартного DropDown
, представление отображает MultiSelectList
через Html.Editor, который берет шаблон редактора из аннотации UIHint в файле проверки.
Добавление/редактирование
Чтобы добавить/отредактировать MultiSelect, я использую отдельный универсальный Find
в репозитории, чтобы вернуть дочерний объект коллекции. Затем выбранные элементы добавляются в контроллер.
Репозиторий
Верните объект для дочерней коллекции, используя другой общий класс (O).
public O GetMulti<O>(int id)
where O : class
{
return context.Set<O>().Find(id);
}
Контроллер
Чтобы создать новый экземпляр родительского объекта, Insert
родителя, а затем выполните итерацию по коллекции дочерних объектов, добавляя каждый по очереди.
[HttpPost]
public ActionResult Create(InterventionTypeAddViewModel model)
{
if (ModelState.IsValid)
{
var a = new tInterventionType();
a.InjectFrom(model);
_repo.Insert(a);
foreach (var outcomeId in model.outcome)
{
tOutcome o = _repo.GetMulti<tOutcome>(outcomeId);
a.tOutcome.Add(o as tOutcome);
}
_repo.Save();
return RedirectToAction("Index");
}
return View(model);
}
Чтобы отредактировать существующий родительский объект, очистите дочернюю коллекцию и добавьте выбранные элементы в соответствии с методом создания.
[HttpPost]
public ActionResult Edit(InterventionTypeUpdateViewModel model, int id)
{
if (ModelState.IsValid)
{
var a = _repo.GetById(id);
a.InjectFrom(model);
a.interventionTypeID = id;
_repo.Update(a);
//clear the child collection (outcome on interventionType)
a.tOutcome.Clear();
//Add current selection
foreach (var outcomeId in model.outcomeID)
{
tOutcome o = _repo.GetMulti<tOutcome>(outcomeId);
a.tOutcome.Add(o as tOutcome);
}
_repo.Save();
return RedirectToAction("Index");
}
return View(model);
}
person
melkisadek
schedule
11.07.2014