可以通过通用存储库同时执行DropDown
和列出。MultiSelect
我已经回答了我自己的问题,DropDowns
所以我不会重复。
列表MultiSelect
对空白列表使用相同的技术,但如果您想在显示当前选择的同时编辑列表,则需要其他内容(与上面的链接一样,我使用selected.js来呈现MultiSelect
输入框)。
楷模
MultiSelectList
我从主 ViewModel 调用了一个 ViewModel 。验证保存在单独的文件中。
多选视图模型
public class MultiSelectViewModel
{
public MultiSelectList Items { get; set; }
}
实体视图模型
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")]
指向以下编辑器模板。类属性适用于selected.js和Twitter Bootstrap框架。
@model WhatWorks.ViewModels.MultiSelectViewModel
@Html.DropDownList("", Model.Items, null, new { @class = "chosen input-xxlarge", multiple = "multiple", })
控制器
在控制器中,我两次调用存储库 - 一次用于控制器所有者实体(在本例中tInterventionType
),一次用于将提供我们MultiSelectList
值的实体(tOutcome
)。实例引用标准泛型 CRUD、Get 和 GetById 方法中的_repo
泛型类型参数 T。_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);
}
要编辑现有的父对象,请清除子集合并按照 create 方法添加当前选定的项目。
[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);
}