首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@Html.DropDownListFor基本用法

@Html.DropDownListFor基本用法
EN

Stack Overflow用户
提问于 2013-11-01 03:29:44
回答 1查看 21.7K关注 0票数 9

我刚刚开始学习MVC4,我必须承认,我对lambda表达式、泛型和匿名类型的依赖有点困难,特别是在存在许多重载函数的情况下。尝试理解HTML助手的工作方式有点让人费解。以"DropDownListFor“助手为例。我试图从我的代码中提取基本要素。这就是为什么你在表格中只看到一列“性别”。希望它在语法上仍然是正确的:

代码语言:javascript
复制
@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>        

模型对象中有两个雇员,一个IEnumerable的Employee,并生成以下HTML

代码语言:javascript
复制
<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方法的第一个参数,

代码语言:javascript
复制
@Html.DropDownListFor(m => employee.Gender, ...

...Do我正确地理解,"m“表示传递给视图的模型类的实例?在我看到的在线示例中,我看到了"m“似乎指的是模型类,但是模型是单个实例类,例如,单个Employee对象,而不是雇员的集合,这里我想显示一个员工列表。我假设DropDownListFor方法的第一个参数的意图是“点/绑定”到模型中的一个属性,所以这就是我创建m => employee.Gender的原因。当模型是员工集合而不是单个员工时,我应该这么做吗?如果是这样的话,我不知道如何为两个下拉列表生成唯一的ID,这两个下拉列表都为名称和ID属性分配了"employee_Gender“。

对于Helper DropDownListFor的第三个参数,

代码语言:javascript
复制
listItems.Find(i => i.Value == employee.Gender).Text

这合理吗?employee.Gender的值要么是"M“,要么是"F”,但是显示文本是“男性”和“女性”。我不明白这个param是用来指定默认的"NO SELECT“第一个值,还是这个param用于从当前员工的下拉列表中选择--或者两者都可以?例如,如果找到,它是否选择指定的文本,并以其他方式添加指定为第一个的文本?参数(如果找不到值)?据我所见,这似乎就是它的工作原理。这个第三段是否可以简化,或者我的例子是否合理?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-01 04:27:52

第1部分:解释Lambda魔术

你并不孤单。Lambdas + MVC使编码变得非常简单,但也使它看起来相当神奇(由于抽象)。

查看DropDownListFor方法的第一个参数.我是否正确地理解"m“表示传递到视图中的模型类的实例?

是。

HTML助手+ Razor中的Lambdas是简单而神奇的,因为他们是在走捷径,实际上并没有向您透露发生了什么。

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

当你打字时

代码语言:javascript
复制
@model IEnumerable<BusinessLayer.Employee>

编辑器读取这些内容,并假设Helper将是HtmlHelper<IEnumerable<BusinessLayer.Employee>>。当需要编译页面时,HTML助手实际上就是这种类型(当然)。

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

看看DropDownListFor,我们可以看到它实际上是DropDownListFor<TModel, TProperty>。我们现在了解到,TModel是视图的模型类型。DropDownListFor知道这一点,因为这个方法是扩展 HtmlHelper<TModel>。因此,DropDownListFor知道传入类型是在视图顶部定义的任何类型。那TProperty

TProperty是返回类型。这是在选择属性时指定的类型。视图为HtmlHelper提供了模型类型,然后模型类型给DropDownListFor,现在您在lambda表达式中:(x => x.Property)您选择属性,然后为您选择类型;在本例中,是字符串(性别)。

第二部分:你的问题

在回答你的问题时,很难不确切地知道你想要达到什么目的。您是否有员工的集合,并且希望为每个员工显示多个性别下拉框,然后保存它们?

在处理集合时,它要复杂一些,因为MVC并不能很好地处理它们;通常最好根据需要编写自己的解决方案。

我真的不喜欢一个视图在页面上收集东西的想法。考虑一下这段逻辑:

你的方式:

  • 收集员工
  • 给员工看一看
  • 拥有视图创建单个SelectListItem
  • 循环遍历并显示每个员工的SelectList

我的方式

  • 收集员工
  • 给员工看一看
  • 让视图循环通过并将每个员工传递到另一个视图(部分)
  • 每个部分只处理一个雇员

有了MVC,一定要把事情分解成小的、逻辑的部分。视图应该是愚蠢的,这意味着它们不应该真正地做任何逻辑或思考。事情变得更容易这样,它确保你的观点不会成长为怪物。

示例解决方案演练

试试这个:

在与您使用的视图相同的文件夹中创建一个名为_EmployeeGender.cshtml的新_EmployeeGender.cshtml。

使用此代码

_EmployeeGender.cshtml

代码语言:javascript
复制
@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>

原始视图

代码语言:javascript
复制
@model IEnumerable<BusinessLayer.Employee>
@{
    ViewBag.Title = "Employees";
}

<h2>Employees</h2>

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

结果

现在让我们看看我们的生成的HTML

代码语言:javascript
复制
<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>

我们可以看到,现在有一个空白的选择,我们的下拉框自动选择与雇员的价值(我创建一个男性和一个女性雇员)。

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

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19720327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档