2011-06-20 106 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