【问题标题】:Asp.net MVC dynamic Html attributesAsp.net MVC 动态 Html 属性
【发布时间】:2011-06-16 11:57:17
【问题描述】:

我的视图文本框、下拉列表等元素很少。它们都有一些像这样创建的独特属性

<%: Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", @someattrt = "someattrt"})%>

我想通过禁用另一个属性来创建我的页面的只读版本。

有谁知道我如何使用可以全局设置的变量来做到这一点?

类似:

If(pageReadOnly){
isReadOnlyAttr  = @disabled = "disabled";
}else 
{
isReadOnlyAttr   =”” 
} 

<%: Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", @someattrt = "someattrt",isReadOnlyAttr})%>

我不想使用 JavaScript 来做到这一点

【问题讨论】:

    标签: c# html asp.net-mvc


    【解决方案1】:

    与其禁用下拉列表,为什么不将其替换为选定的选项...如果您要为很多东西这样做,您应该考虑拥有一个只读视图和一个可编辑视图...

    <% if (Model.IsReadOnly) { %>
        <%= Model.MyModel.MyType %>
    <% } else { %>
        <%= Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", someattrt = "someattrt"})%>
    <% } %>
    

    顺便说一句,如果属性名是保留字,如“class”,则只需用“@”转义即可。

    更新

    好的。我确实有一个答案 - 但前提是您在实施之前阅读了这些内容。

    MVC 就是分离关注点。将逻辑放在视图中特别关注的控制器中是对 MVC 的滥用。请不要这样做。任何特定于视图的内容,例如 HTML、属性、布局——这些都不应该出现在“controllerville”中。控制器不必更改,因为您想更改视图中的某些内容。

    了解 MVC 试图实现的目标以及以下示例打破了整个模式并将视图内容放在应用程序中完全错误的位置非常重要。

    正确的解决方法是拥有一个“读取”视图和一个“编辑”视图——或者在视图中放置任何条件逻辑。但这是一种做你想做的事的方法。 :(

    将此属性添加到模型。

    public IDictionary<string, object> Attributes { get; set; }
    

    在控制器中可以有条件地设置属性:

    model.Attributes = new Dictionary<string, object>();
    model.Attributes.Add(@"class", "test");
    if (isDisabled) {
        model.Attributes.Add("disabled", "true");
    }
    

    使用视图中的属性:

    <%= Html.TextBoxFor(model => model.SomeValue, Model.Attributes)%>
    

    【讨论】:

    • 这个视图有很多东西,我们只需要它来做一些你能做的“演示”。我试图避免创建单独的视图或在每个元素上放置“if”语句。我宁愿从表单中删除提交按钮并添加禁用属性。这可能吗?
    • 我添加了一个例子。仅仅因为它是可能的并不意味着你必须这样做......请阅读示例上方的内容。
    • 感谢您的更新,这是我最初的方法,但不同的元素具有不同的属性,因此我无法将相同的 model.Attributes 传递给所有元素。
    • 您可以拥有不同的属性集合,或者您可以将视图上的字典与模型上禁用的属性字典合并。
    【解决方案2】:

    我做了一些与我想的类似的事情-基本上我有几个不同的系统用户,其中一组在网站上具有只读权限。为了做到这一点,我在每个视图模型上都有一个变量:

    public bool Readonly { get; set; }
    

    根据他们的角色权限在我的模型/业务逻辑层中设置。

    然后,我为 DropDownListFor Html Helper 创建了一个扩展,它接受一个布尔值,指示下拉列表是否应为只读:

    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    
    public static class DropDownListForHelper
    {
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> dropdownItems, bool disabled)
        {
            object htmlAttributes = null;
    
            if(disabled)
            {
                htmlAttributes = new {@disabled = "true"};
            }
    
            return htmlHelper.DropDownListFor<TModel, TProperty>(expression, dropdownItems, htmlAttributes);
        }
    }
    

    请注意,您也可以创建其他采用更多参数的实例。

    在我看来,我只是为我的 html 助手扩展导入了命名空间,然后将视图模型变量只读传递给 DropDownListFor Html 助手:

    <%@ Import Namespace="MvcApplication1.Helpers.HtmlHelpers" %>
    
    <%= Html.DropDownListFor(model => model.MyDropDown, Model.MyDropDownSelectList, Model.Readonly)%>
    

    我为 TextBoxFor、TextAreaFor 和 CheckBoxFor 做了同样的事情,它们似乎都运行良好。希望这会有所帮助。

    【讨论】:

    • 嗨,感谢重播,是的,这就是我所追求的
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 2011-04-13
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多