如何从控制器内轻松创建下拉列表

本文关键字:创建 下拉列表 控制器 | 更新日期: 2023-09-27 17:59:48

我有一个部分视图,其中包含一些看起来相同的<div>,并且每个视图都包含一个下拉列表。现在,下拉列表中的选定值通常不同。初始值列表来自某些外部来源。所以这是行不通的:

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>

我当然可以为每顿饭创建另一个部分视图,但我不想进入部分视图层次结构并在另一个部分视图中创建部分视图(尽管 Leo DiCaprio 会喜欢这样(

你们能给我一个建议吗?

如何从控制器内轻松创建下拉列表

这就是我会做的。第一件事是摆脱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>

现在有更多的循环、强制转换、错误命名的输入控件。你会得到强类型,智能感知启用视图,很美味:-(

现在,当您查看控制器操作时,一定有一些事情困扰着您:域模型和视图模型之间的重复映射代码。进入AutoMapper的世界,你会得到非常漂亮的代码。