@ Html.DropDownListFor基本用法

Cha*_*adD 9 c# asp.net-mvc asp.net-mvc-4

我刚刚开始学习MVC4,我必须承认我对所有依赖lambda表达式,泛型和匿名类型都有一点挑战,特别是当有很多重载函数时.尝试理解HTML帮助程序的工作方式有点令人困惑.以"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>        
Run Code Online (Sandbox Code Playgroud)

Model对象中有两个Employees,一个IEnumerable of Employee,并生成以下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>                
Run Code Online (Sandbox Code Playgroud)

查看DropDownListFor方法的第一个参数,

@Html.DropDownListFor(m => employee.Gender, ...
Run Code Online (Sandbox Code Playgroud)

...我是否正确理解"m"表示传递给View的模型类的实例?在我看过的在线示例中,我看到过"m"似乎引用模型类但模型是单个实例类的示例,例如,单个Employee对象,而不是Employees的集合.就是这里我要显示Employees的表列表.我假设DropDownListFor方法的第一个参数的意图是对属性的 "点/绑定"在模型中,这就是我制作m => employee.Gender的原因.当模型是Employees而不是单个Employee的集合时,这是我应该做的吗?如果是这样,我对如何为两个下拉列表生成唯一ID感到困惑,这两个下拉列表都为NAME和ID属性分配了"employee_Gender".

对于Helper DropDownListFor的第3个参数,

listItems.Find(i => i.Value == employee.Gender).Text
Run Code Online (Sandbox Code Playgroud)

这合理吗?employee.Gender的值为"M"或"F",但显示文本为"男性"和"女性".我很困惑这个参数是否用于指定默认的"NO SELECT"第一个值,或者该参数是否用于从下拉列表中选择当前Employee的值---或者它可以同时执行这两个值?例如,它是否选择了找到的文本,否则添加指定为FIRST的文本参数如果找不到值?这看起来就像我看到的那样.这第三个参数可以简化还是我的例子合理?

感谢您耐心阅读我的许多问题,试图更好地理解这一点.

Row*_*man 25

第1部分:解释Lambda魔法

你不是一个人.Lambdas + MVC使编码变得容易,但它们也使它看起来相当神奇(由于抽象).

查看DropDownListFor方法的第一个参数[...]我是否正确理解"m"表示传递给View的模型类的实例?

是.

Razor中的HTML Helpers + Lambdas简单而神奇,因为它们采用了一种捷径,并没有真正向您揭示正在发生的事情.

首先,我们来看看@Html.我们知道@开始我们的Razor语法然后Html是魔术.实际上,Html是一个HtmlHelper对象,它会自动初始化并提供给您.更具体地说,它是一个HtmlHelper<TModel>.Razor HTML编辑器非常智能,并且提前知道TModel将基于您所说的此视图的模型类型的类型.这就是为什么你有这么多intellisense.

当你输入

@model IEnumerable<BusinessLayer.Employee>
Run Code Online (Sandbox Code Playgroud)

编辑器会读取它并立即假设HTML Helper将是HtmlHelper<IEnumerable<BusinessLayer.Employee>>.当编译页面时,HTML帮助程序实际上就是那种类型(当然).

那么DropDownListFor或者其他任何扩展方法呢?

DropDownList我们可以看到它实际上DropDownListFor<TModel, TProperty>.我们现在明白TModel是我们视图的模型类型.DropDownListFor我知道这个,因为这个方法正在扩展 HtmlHelper<TModel>.因此DropDownListFor知道传入类型是在视图顶部定义的任何类型.怎么样TProperty

TProperty是返回类型.这是您选择房产时指定的类型.视图为HtmlHelper提供模型类型,然后为模型类型提供DropDownList,现在您在lambda表达式中:(x => x.Property)选择属性然后为您选择类型; 在这种情况下是一个字符串(性别).

第2部分:你的问题

如果不确切知道自己要实现的目标,就很难回答你的问题.您是否有一个Employees集合,并且您想为每个人显示多个性别下拉框,然后保存它们?

处理集合时,它有点棘手,因为MVC不能很好地处理它们; 通常最好根据您的需要编写自己的解决方案.

我真的不喜欢单个视图在页面上获取东西的想法.考虑一下这条逻辑:

你的方式:

  • 获取员工的集合
  • 为员工提供一个视图
  • 有视图创建一个SelectListItem
  • 循环并显示每个Employee的SelectList

我的方式

  • 获取员工的集合
  • 为员工提供观点
  • 让视图循环并将每个Employee传递给另一个视图(部分)
  • 每个部分处理单个员工

使用MVC,请尝试将内容分解为小的逻辑部分.意见应该是愚蠢的; 意思是他们不应该真正做任何逻辑或思考.事情变得越来越容易,它确保你的观点不会变成怪物.

示例解决方案演练

试试这个:

在与您正在使用的视图相同的文件夹中创建一个名为_ 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>
Run Code Online (Sandbox Code Playgroud)

你的原始观点

@model IEnumerable<BusinessLayer.Employee>
@{
    ViewBag.Title = "Employees";
}

<h2>Employees</h2>

<table>
    @foreach (var employee in Model) 
    {
        Html.RenderPartial("_EmployeeGender", employee);
    }
</table>
Run Code Online (Sandbox Code Playgroud)

结果

现在让我们看一下我们生成的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>
Run Code Online (Sandbox Code Playgroud)

我们可以看到现在有一​​个空白的选择,我们的下拉框会自动选择Employee的值(我创建一个男性和一个女性员工).

请注意,HTML idnameHTML属性是相同的.如果您想提交包含这些值的表单,则需要更多工作.但这对你来说是一个合理的起点.