在ASP.NET MVC中如何将“视图模型”包含到“视图”中存在困惑

问题描述:

从阅读很多关于如何在各种网站上设置下拉菜单的教程,我已经设法将几件事情合并起来,仍然卡住。在ASP.NET MVC中如何将“视图模型”包含到“视图”中存在困惑

我已经告诉我下面的代码应该被包含在一个视图模型,它是目前在我的视图顶部:

var genderItems = new List<ListItem> 
    { 
      new ListItem { Text = "Unisex", Value = "0" }, 
      new ListItem { Text = "Female", Value = "1" }, 
      new ListItem { Text = "Male", Value = "2" } 
    }; 

var statusItems = new List<ListItem> 
    { 
      new ListItem { Text = "Inactive", Value = "0" }, 
      new ListItem { Text = "Active", Value = "1" } 
    }; 

在同一视图中我一直在使用这个代码生成一个下拉框:

@Html.DropDownList("RoomGender", new SelectList(genderItems, "Value", "Text", Model.RoomGender)) 

可能有人请解释一下我应该如何摘要,然后将它传递给视图不删除已连接Room模型,我有,因为这是模型,用于数据为数据库。

这可能很简单,我试过研究它,但我真的很努力将它拼凑在一起。

+1

您也可以使用枚举用于显示性别 –

+0

我试图用枚举前几天的下拉菜单,拥有一切存储到SE虽然很好,但为选择下拉元素的值而挣扎。 –

+0

为了您对模型和viewModel的困惑,你可以看看这一个http://stackoverflow.com/questions/4061440/asp-net-mvc-model-vs-viewmodel和使用枚举的一部分,我会添加一些代码! –

是不是这个Room模型已经是您的视图模型?视图模型只是一个包含视图需要的数据的类。约定它们倾向于被称为视图模型以将它们与领域模型分开。在你的情况下,你可以添加几个属性RoomStatusItemsGenderItems。或者,使用Room和2个列表属性创建一个RoomViewModel,然后将其传递给View。

理想情况下,您将创建一个RoomViewModel并为您需要在视图中显示的所有数据创建属性。这并不需要与你的域对象的结构相匹配。在你的MVC层中,你需要从视图中检索数据的域对象,并在视图模型创建期间映射这些属性。您可以手动执行此操作,也可以使用Automapper之类的工具。

+0

所以说例如我使用'房间'和'Bunk'类(我已经迁移到数据库),那些是我的域模型? 当生成控制器时,我将'Room'类设置为我的模型,是否应该创建另一个类作为我的域模型的包装类型? –

+0

更详细地更新了我的答案。这有帮助吗? – levelnis

+0

这确实有帮助!虽然我有点困惑,如果我有一个'RoomViewModel'坐在中间,一个使用EF5的自动生成的控制器(创建索引,创建,细节,编辑,删除)如何能够将数据存储到数据库? –

这是一个用于绑定枚举性别到您的看法。 假设学生是我绑定到视图模型,

namespace MyApp.Models 
{ 
    public class Student 
    { 
      public int Id { get; set; } 
      public string FirstName { get; set; } 
      public string LastName { get; set; } 
      public Gender Gender { get; set; } 
    } 

    public enum Gender 
    { Male = 0, Female = 1 } 
} 

,然后在视图

@Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(typeof(MyApp.Models.Gender)))) 

我希望你得到它吧!

+0

谢谢您的解释,是否可以使用相同的'Student'类来附加'DbContext''DbSet'? –

+0

是的,你可以在你的DbContext类中有这个 –

+0

因为这些枚举将在多个地方使用,所以我应该真的在创建单独的枚举类文件呢? 这是否会影响他们与下降的观点倒访问的方法是什么? 也做这个挑选出默认选择性别? –

为了获得下拉列表数据到视图,我建议将数据添加到ViewBag

你可以看到这样一个在这里例如: http://jnye.co/Posts/12/creating-cascading-dropdownlists-using-mvc-4-and-jquery

首先值添加到您的ViewBag。通常我把这个在它自己的方法,因为它需要每个页面加载时间(包括,在一个失败的形式subission显示时)被称为:

//You can keep your current list setup, I have simply shortened it for brevity 
var genderItems = new List<string> {"Unisex", "Female", "Male"}; 
ViewBag.Genders = new SelectList(genderItems); 

然后在您的视图:

@Html.DropDownList("gender", ViewBag.Genders as SelectList) 

或者,如果你想要的结果绑定到一个属性上您的视图模型:

@Html.DropDownListFor(m => m.Property, ViewBag.Genders as SelectList) 
+0

为什么在OP已经使用视图模型时使用ViewBag?你打算如何进行单元测试? – levelnis

+0

鉴于OP正在讨论下拉列表,我认为我们可以假设视图模型用于定义去往和来自服务器的数据。下拉列表中的选项是视图需要呈现的附加数据,并且不应在每次提交表单时将其发送回服务器,也不应将视图模型更改为适应此视图数据,这是“ViewData”(其中'ViewBag'包装)。'ViewBag'可以与视图模型结合使用,所以OP已经使用视图模型的事实不是问题,但实际上,我认为是预期的。 – NinjaNye

+0

我不希望这会变成一个'ViewBag'和'ViewModel'辩论,因为这已经完成了,但是dropdownlist选项不会每次都回发到服务器。只有选定的值被回传。在特定于该视图的'ViewModel'中封装视图所需的所有数据使得清楚哪些数据是必需的。为了突出显示所需的数据而不是回发,我喜欢用一个'ViewModel'来显示,以及一个等效的'Command'来回传给服务器。 'Command'不需要选项列表,只是选择的值。 – levelnis