c# - @Html.DropDownListFor 基本用法

标签 c# asp.net-mvc asp.net-mvc-4

我刚刚开始学习 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是魔法。实际上,HtmlHtmlHelper自动初始化并提供给您的对象。更具体地说,它是 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 在页面上获取事物集合的想法。考虑这个逻辑:

你的方式:
  • 获取员工集合
  • 让员工查看
  • 让 View 创建单个 SelectListItem
  • 循环并显示每个员工的 SelectList

  • 我的方式
  • 获取员工集合
  • 给员工看
  • 让 View 循环并将每个员工传递到另一个 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>
    

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

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

    关于c# - @Html.DropDownListFor 基本用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19720327/

    相关文章:

    asp.net - 根据电子邮件地址将 OAuth 帐户与现有帐户合并

    html - 如何在 MVC 3 Razor 中显示解码后的编码 HTML?

    c# - 如何在MVVM Light和WPF中从父级创建子级窗口?

    c# - 为什么谷歌地图在几次回复后卡住页面

    c# - 排列/测量问题 - WPF 中的布局是否损坏?

    .net - 编辑器模板不适用于 DisplayFormat

    c# - 我不能在此处将我的 ADO.NET 实体模型实例包装在 using 语句中吗?

    c# - 在 C# MVC 中将 XML 数据绑定(bind)到模型

    asp.net-mvc - 为什么我的 http 帖子从我的 View 模型返回 null

    c# - Appfabric GetObjectsByTag 反序列化问题