具有数据属性的SelectListItem

Bar*_*xto 65 asp.net-mvc html5 html-helper selectlist custom-data-attribute

无论如何在ViewModel上预先填充了具有数据属性的SelectList吗?

我想要做

@Html.DropdownListFor(m=> m.CityId, Model.Cities);
Run Code Online (Sandbox Code Playgroud)

所以它生成如下代码:

<select id="City" class="location_city_input" name="City">
    <option data-geo-lat="-32.522779" data-geo-lng="-55.765835" data-geo-zoom="6" />
    <option data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13" data-geo-name="Montevideo" data-child=".state1" value="1">Montevideo</option>               
    <option data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13" data-geo-name="Canelones, Ciudad de la Costa" data-child=".state41" value="41">Ciudad de la Costa</option>
</select>
Run Code Online (Sandbox Code Playgroud)

Kyl*_*Mit 103

这是简单的解决方案.

并非所有内容都必须使用.NET代码中的扩展方法编写.MVC的一大优点是它可以让您轻松访问构建自己的HTML.

使用MVC4,您可以使用帮助程序HTML.NameFor和表达式获取表达式树上元素的id和名称HTML.IdFor

<select name="@Html.NameFor(Function(model) model.CityId)"
        id="@Html.IdFor(Function(model) model.CityId)"
        class="location_city_input">
    @For Each city In Model.Cities
        @<option value="@city.Value"
                 @(If(city.Value = Model.CityId, "selected", ""))
                 data-geo-lat="@city.Lat"
                 data-geo-lng="@city.Lng"
                 data-geo-zoom="@city.Zoom">
            @city.Text
        </option>
    Next
</select>
Run Code Online (Sandbox Code Playgroud)

假设Model.Cities是一组公开每个属性的项目.那么你应该全力以赴.

如果您想要可重用性,请考虑将其作为"Enumerable of Cities"的任何内容的编辑器模板

  • 因为razor2你可以简单地做`selected ="@ city.Value == Model.CityId"`它会产生正确的标记('selected ="选择"`或什么都没有) (5认同)
  • 你如何使这仍然与验证工作?当存在验证错误时,我的选择不再正确地以红色突出显示. (4认同)
  • @Diego发布的代码在我添加括号后才起作用:`selected ="@(city.Value == Model.CityId)"` (3认同)
  • 有趣......我不知道html.namefor等我会试一试 (2认同)

ata*_*ati 12

您必须扩展SelectListItem,然后扩展DropDownListFor以使用扩展的SelectListItem.

看看这个解决方案:

在Html.DropDownList中的<option>下添加html类标记

  • 我不知道为什么你觉得它很难看,但对我来说似乎更合乎逻辑.每个SelectListItem代表最终html中的选项标记,您需要做的是将自定义html属性添加到选项标记(SelectListItem),因此只扩展SelectListItem才有意义. (4认同)
  • 这看起来是正确的答案,但看起来有点难看。我认为我宁愿自己编写选择,也不愿扩展 SelectListItem 和 DropDownListFor 。我不知道。 (2认同)

xr2*_*0xr 7

这是我最终在没有扩展的情况下完成它但仍然启用不显眼的验证以继续工作并绑定到 ViewModel 属性的方式。

创建了一个 Html Helper 以获取字符串形式的验证属性:

    public static IHtmlString GetUnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertySelector)
    {
        string propertyName = html.NameFor(propertySelector).ToString();
        ModelMetadata metaData = ModelMetadata.FromLambdaExpression(propertySelector, html.ViewData);
        IDictionary<string, object> attributeCollection = html.GetUnobtrusiveValidationAttributes(propertyName, metaData);

        return html.Raw(String.Join(" ", attributeCollection.Select(kvp => kvp.Key + "=\"" + kvp.Value.ToString() + "\"")));
    }
Run Code Online (Sandbox Code Playgroud)

select在视图的列表中使用此助手:

<select name="@Html.NameFor(m => m.CityId)" id="@Html.IdFor(m => m.CityId)"
    @Html.GetUnobtrusiveValidationAttributesFor(m => m.CityId)
    class="location_city_input">
    @foreach(var city in Model.Cities)
    {
        <option value="@city.Id.ToString()" @(city.Id == Model.CityId ? "selected" : "") 
            data-geo-lat="@city.Lat" data-geo-lng="@city.Lng" data-geo-zoom="@city.Zoom">
            @city.Name
        </option>
    }
</select>
Run Code Online (Sandbox Code Playgroud)

这将输出如下内容:

<select id="CityId" name="CityId" 
    data-val-required="The SelectedTaxRateID field is required." data-val="true" 
    class="location_city_input">
    <option value="1" selected data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13">Montevideo</option>               
    <option value="41" data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13">Ciudad de la Costa</option>
</select>
Run Code Online (Sandbox Code Playgroud)

我将把条件data-属性留给你,因为这些只是形成适当的 Razor 表达式的问题。


小智 6

MVC 将对象名称转换为属性名称时,会将“_”替换为“-”,因此其:

@Html.DropDownList(a=>a.websiteid, Model.GetItems, new{ data_rel="selected" })
Run Code Online (Sandbox Code Playgroud)

不是我的答案,答案来自 ASP>NET 论坛的关于 bruce (sqlwork.com)。

如何将 data-rel="selected" 属性添加到 htmlAttributes 的下拉列表中?

只是想提供帮助,因为这使我免于编写黑客代码!请享用。

  • 这只是将 data-rel 添加到 `select` 而不是每个 `option` (7认同)