我刚刚开始学习 MVC4,我必须承认我对 lambda 表达式、泛型和匿名类型的所有依赖有点挑战,尤其是当有许多重载函数时。尝试理解 HTML Helpers 的工作原理有点令人困惑。以“DropDownListFor”Helper 为例。我试图从我的代码中提取要领。这就是为什么您在表格中只看到一个“性别”列。希望它在语法上仍然正确:
@model IEnumerable<BusinessLayer.Employee>
<table>
@foreach (var employee in Model)
{
<tr>
<td>
@{
var listItems = new List<SelectListItem>()
{
new SelectListItem {Text = "Male", Value = "M"},
new SelectListItem {Text = "Female", Value = "F"}
};
@Html.DropDownListFor(m => employee.Gender, listItems, listItems.Find(i => i.Value == employee.Gender).Text)
}
</td>
</tr>
}
</table>
Model对象中有两个Employees,一个Employee的IEnumerable,生成如下HTML
<table>
<tr>
<td>
<select id="employee_Gender" name="employee.Gender"><option value="">Male</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</tr>
</td>
<select id="employee_Gender" name="employee.Gender"><option value="">Female</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</td>
</table>
查看 DropDownListFor 方法的第一个参数,
@Html.DropDownListFor(m => employee.Gender, ...
...我是否正确理解“m”代表传递给 View 的模型类的实例?在我看到的在线示例中,我看到了“m”似乎是指模型类但模型是单个实例类的示例,例如单个 Employee 对象,而不是Employees的集合在这种情况下,我想显示员工的表格列表。我假设 DropDownListFor 方法的第一个参数的意图是“指向/绑定(bind)”到模型中的一个属性,所以这就是我制作 m => employee.Gender 的原因。这是我在模型时应该做的吗是员工的集合而不是单个员工?如果是这样,我很困惑如何为两个下拉列表生成唯一 ID,这两个下拉列表都为 NAME 和 ID 属性分配了“employee_Gender”。
对于 Helper DropDownListFor 的第三个参数,
listItems.Find(i => i.Value == employee.Gender).Text
这合理吗? employee.Gender 的值为“M”或“F”,但显示文本为“Male”和“Female”。我很困惑这个参数是否用于指定默认的“NO SELECT”第一个值,或者这个参数是否用于从下拉列表中选择当前员工的值——或者它可能两者都做?例如,如果找到,它是否选择指定的文本,否则添加指定为 FIRST 的文本?如果找不到该值的参数?从我所看到的情况来看,这似乎是它的工作方式。这第三个参数可以简化还是我的例子合理?
感谢您耐心阅读我的许多问题,以更好地理解这一点。
最佳答案
第 1 部分:解释 Lambda 魔法
你不是一个人。 Lambdas + MVC 使编码变得容易,但它们也使它看起来相当神奇(由于抽象)。
Looking at the first param of the DropDownListFor Method [...] Do I understand correctly that the "m" represents the instance of the model class that was passed into the View?
是的。
Razor 中的 HTML Helpers + Lambdas 既简单又神奇,因为它们走的是捷径,实际上并没有向您揭示发生了什么。
首先我们来看看
@Html
.我们知道@
开始我们的 Razor 语法,然后是 Html
是魔法。实际上,Html
是 HtmlHelper自动初始化并提供给您的对象。更具体地说,它是 HtmlHelper<TModel>
. Razor HTML 编辑器很智能,可以根据您所说的 View 模型类型提前知道 TModel 将是什么类型。这就是为什么你有这么多智能。当您键入
@model IEnumerable<BusinessLayer.Employee>
编辑器读取并假设 HTML Helper 将是
HtmlHelper<IEnumerable<BusinessLayer.Employee>>
.当需要编译页面时,HTML 助手实际上就是那种类型(当然)。那么
DropDownListFor
呢?或任何其他扩展方法?看DropDownListFor我们可以看到它实际上是
DropDownListFor<TModel, TProperty>
.我们现在明白 TModel 是我们 View 的模型类型。 DropDownListFor
知道这一点,因为方法是 延长 HtmlHelper<TModel>
.因此 DropDownListFor 知道传入的类型是 View 顶部定义的任何类型。 TProperty
呢? ?TProperty
是返回类型。这是您在选择属性时指定的类型。该 View 为 HtmlHelper 提供模型类型,然后他为 DropDownListFor 提供模型类型,现在您处于 lambda 表达式中:(x => x.Property)
您选择属性,然后为您选择类型;在这种情况下是 字符串 (性别)。第 2 部分:您的问题
如果不确切知道您要达到的目标,就很难回答您的问题。您是否有一组员工,并且您想为每个员工显示多个性别下拉框,然后保存它们?
在处理集合时,它有点棘手,因为 MVC 不能开箱即用地处理它们;通常最好根据您的需要编写自己的解决方案。
我真的不喜欢单个 View 在页面上获取事物集合的想法。考虑这个逻辑:
你的方式:
我的方式
使用 MVC 确实尝试将事物分解为小的、符合逻辑的部分。观点应该是愚蠢的;这意味着他们不应该真正做任何逻辑或思考。通过这种方式,事情变得更容易,它可以确保你的观点不会变成怪物。
示例解决方案演练
试试这个:
在与您使用的 View 相同的文件夹中创建一个名为 _EmployeeGender.cshtml 的新 PartialView。
使用此代码
_EmployeeGender.cshtml
@model BusinessLayer.Employee
<tr>
<td>
@{
var listItems = new List<SelectListItem>()
{
new SelectListItem {Text = "Male", Value = "M"},
new SelectListItem {Text = "Female", Value = "F"}
};
@Html.DropDownListFor(m => m.Gender, listItems, string.Empty)
}
</td>
</tr>
您原来的看法
@model IEnumerable<BusinessLayer.Employee>
@{
ViewBag.Title = "Employees";
}
<h2>Employees</h2>
<table>
@foreach (var employee in Model)
{
Html.RenderPartial("_EmployeeGender", employee);
}
</table>
结果
让我们看看我们的生成的 HTML 现在:
<table>
<tr>
<td>
<select id="Gender" name="Gender"><option value=""></option>
<option selected="selected" value="M">Male</option>
<option value="F">Female</option>
</select>
</td>
</tr><tr>
<td>
<select id="Gender" name="Gender"><option value=""></option>
<option value="M">Male</option>
<option selected="selected" value="F">Female</option>
</select>
</td>
</tr></table>
我们可以看到现在有一个空白选择,并且我们的下拉框自动选择了员工的值(我创建了一名男性和一名女性员工)。
请注意该
id
和 name
HTML 属性是相同的。如果您想提交具有这些值的表单,则需要更多的工作。但这对您来说是一个合理的起点。
关于c# - @Html.DropDownListFor 基本用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19720327/