2011-06-20 22 views
1

我有一個局部視圖,其中包含幾個<div>,它們看起來相同,並且它們每個都包含一個DropdownList。現在,DropdownLists中的選定值通常不同。最初的價值清單來自一些外部來源。 這樣我就不會工作:如何從控制器內輕鬆創建DropDownList

public PartialViewResult GetMeals() 
{ 
     var meals = DataContext.GetMeals(); 
     ViewBag.Units = new SelectList(DataContext.GetUnits,"Id","Name"); 

     return PartialView("_Meals", meals); 
} 

@foreach (var m in Meals) 
{ 
    <div> 
     @Html.DropDownList("Units", ViewBag.Units as List<SelectListItem>) 
    <dig> 

我當然可以創建每餐另一部分觀點,但我不想進入一個局部視圖層次結構和內部的另一部分創建部分(儘管利奧迪卡普里奧會喜歡的)

你們能給我一個建議嗎?

回答

2

這是我會做的。這首先是擺脫ViewBag。然後定義視圖模型:

public class MealViewModel 
{ 
    public string MealDescription { get; set; } 

    public string SelectedUnit { get; set; } 
    public IEnumerable<SelectListItem> Units { get; set; } 
} 

裏面你只放你的觀點(在這種情況下,局部視圖)需要這個視圖模型。

,然後我有我的控制器操作從彙總數據,無論你想填充此視圖模型:

public ActionResult GetMeals() 
{ 
    var meals = DataContext.GetMeals().ToList(); // <-- being eager with .ToList() 
    var units = DataContext.GetUnits().ToList(); // <-- being eager with .ToList() 
    var viewModel = meals.Select(meal => new MealViewModel 
    { 
     MealDescription = meal.Description, 
     SelectedUnit = meal.UnitId, 
     Units = units.Select(unit => new SelectListItem 
     { 
      Value = unit.Id.ToString(), 
      Text = unit.Name 
     }) 
    }); 
    return PartialView("_Meals", viewModel); 
} 

和內部部分_Meals我會使用編輯器模板:

@model IEnumerable<MealViewModel> 
@Html.EditorForModel() 

和最後,我會定義一個編輯模板用於進餐:(~/Views/Shared/EditorTemplates/MealViewModel.cshtml)將爲模型的每個元素渲染:

@model MealViewModel 
<h3>@Html.DisplayFor(x => x.MealDescription)</h3> 
<div>  
    @Html.DropDownListFor(
     x => x.SelectedUnit, 
     new SelectList(Model.Units) 
    ) 
</div> 

現在更多循環,轉換,錯誤地命名輸入控件。您可以獲得強類型,Intellisense啓用的視圖,美味:-)

現在,當您查看控制器操作時,必須有一些令您困擾的事情:您的域模型和視圖模型之間的重複映射代碼。進入AutoMapper的世界,你會得到非常漂亮的代碼。

+1

達林......你是最棒的!一如既往... – Agzam