DropDown
汎用リポジトリを介してとMultiSelect
Lists の両方を行うことができます。
私はすでに自分の質問に答えているDropDowns
ので、繰り返しません。
リストは空のMultiSelect
リストに対して同じ手法を使用しますが、現在の選択を表示しながらリストを編集する場合は、別のものが必要です (上記のリンクと同様に、入力ボックスをレンダリングするためにselected.jsを使用します)。MultiSelect
モデル
MultiSelectList
メインの ViewModel から呼び出すViewModel があります。検証は別のファイルに保持されます。
MultiSelect 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")]
、次のエディター テンプレートを指します。クラス属性は、choose.jsおよびTwitter Bootstrapフレームワーク用です。
@model WhatWorks.ViewModels.MultiSelectViewModel
@Html.DropDownList("", Model.Items, null, new { @class = "chosen input-xxlarge", multiple = "multiple", })
コントローラ
コントローラーでは、リポジトリーを 2 回呼び出します。1 回目はコントローラーの所有者エンティティー (この場合はtInterventionType
) で、もう 1 回はMultiSelectList
値を提供するエンティティー ( tOutcome
) です。_repo
インスタンスは、標準のジェネリック CRUD、Get、および GetById メソッドのジェネリック型パラメーター 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
、検証ファイルの UIHint 注釈からエディター テンプレートを取得する Html.Editor を介して をレンダリングします。
追加・編集
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);
}