如何有条件地只读编辑器?

时间:2015-03-19 19:24:01

标签: asp.net-mvc html5 asp.net-mvc-5

我有这行代码:

@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })

我的视图数据字典中有一个名为Readonly的变量。如果ViewBag.Readonly为真,如何将数量设为只读,如果为假,则如何只读取?

简单的事情,但Razor与HTML(古老)的结合使得其他简单的事情变得不可能。

编辑:

我不想使用if语句。这是最后的手段,因为它违反了DRY,过去我因为没有跟随而多次被严重烧伤。

我上面的这一行确实有效,因为它使文本框只读。我需要根据我的观点状态制作这个条件。

解决方案:

我使用了以下内容。它仍然是DRY违规,但它将它减少到一行。

@Html.EditorFor(model => model.Quantity, new { htmlAttributes = ViewBag.Readonly ? (object)new { @class = "form-control", @readonly = "htmlsucks" } : (object)new { @class = "form-control" } })

6 个答案:

答案 0 :(得分:24)

编辑:MVC 5

<强>控制器

ViewBag.Readonly=true;//false

查看

@Html.EditorFor(model => model.Quantity, ViewBag.Readonly ? (object)new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" }} : new { htmlAttributes = new { @class = "form-control" } })

答案 1 :(得分:4)

这很简单。这样做。

@if((bool)ViewBag.Readonly)
{
    @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
}
else
{
    @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
}

答案 2 :(得分:2)

如果你的视图中有很多地方有这样的逻辑,我认为使用库FluentDataAnnotations可以让你的代码干净清晰。

如果您熟悉FluentValidator,则使用它非常相似。

在您的情况下,所有逻辑都将从视图移动到模型注释类。在你将只有@Html.EditorFor(model => model.Quantity)

它甚至允许在条件中使用模型属性 例如 this.When(model => !model.AllowEditPhone, () => { this.For(m => m.Phone).SetReadOnly(false); });

这里需要ASP.NET MVC 5的NuGet package。 (对ASP.NET Core的支持正在进行中。)

答案 3 :(得分:1)

今天,我不得不处理这个问题,因为我必须为Html.TextBoxFor元素设置一个“只读”属性。我最终编写了以下帮助程序方法,使我可以在解决问题的同时保持DRY方法:

/// <summary>
/// Gets an object containing a htmlAttributes collection for any Razor HTML helper component,
/// supporting a static set (anonymous object) and/or a dynamic set (Dictionary)
/// </summary>
/// <param name="fixedHtmlAttributes">A fixed set of htmlAttributes (anonymous object)</param>
/// <param name="dynamicHtmlAttributes">A dynamic set of htmlAttributes (Dictionary)</param>
/// <returns>A collection of htmlAttributes including a merge of the given set(s)</returns>
public static IDictionary<string, object> GetHtmlAttributes(
    object fixedHtmlAttributes = null,
    IDictionary<string, object> dynamicHtmlAttributes = null
    )
{
    var rvd = (fixedHtmlAttributes == null)
        ? new RouteValueDictionary()
        : HtmlHelper.AnonymousObjectToHtmlAttributes(fixedHtmlAttributes);
    if (dynamicHtmlAttributes != null)
    {
        foreach (KeyValuePair<string, object> kvp in dynamicHtmlAttributes)
            rvd[kvp.Key] = kvp.Value;
    }
    return rvd;
}

它可以通过以下方式使用:

var dic = new Dictionary<string,object>();
if (IsReadOnly()) dic.Add("readonly", "readonly");
Html.TextBoxFor(m => m.Name, GetHtmlAttributes(new { @class="someclass" }, dic))

该代码非常不言自明,但是我还在博客上的this post中解释了其基本逻辑。

答案 4 :(得分:0)

通过编写辅助方法,可以尊重DRY委托人。

    using System.Web.Mvc.Html;

    public static MvcHtmlString Concat(this MvcHtmlString first, params MvcHtmlString[] strings)
    {
        return MvcHtmlString.Create(first.ToString() + string.Concat(strings.Select(s => ( s == null ? "" : s.ToString()))));
    }

    public static MvcHtmlString ConditionalEditFor<TModel,TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression)
    {
        helper.ConditionalEditFor(EditCondition,Expression,false);
    }

    public static MvcHtmlString ConditionalEditFor<TModel, TValue>(this HtmlHelper<TModel> helper, bool EditCondition, Expression<Func<TModel, TValue>> Expression, bool IncludeValidationOnEdit)
    {
        if (EditCondition)
        {
            if (!IncludeValidationOnEdit)
                return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression);
            else
                return EditorExtensions.EditorFor<TModel, TValue>(helper, Expression).Concat(ValidationExtensions.ValidationMessageFor<TModel, TValue>(helper, Expression));
        }
        else
        {
            return DisplayExtensions.DisplayFor<TModel, TValue>(helper, Expression);
        }
    }

然后在你看来:

添加条件语句以确定只读 例如

@{bool IsReadOnly = YourCondition;}

@Html.ConditionalEditFor(!IsReadOnly/*condition*/, model => model.YourProperty,true /*do validation*/)

然后你可以添加你想要的任何其他覆盖。

答案 5 :(得分:0)

JQUERY读取SETUP_TYPE控件值并使用特定的CSS选择器禁用控件。

$(function () {
    if ($("#SETUP_TYPE").val() == "1") { $('.XXX').attr('disabled', true); }
})

$(function () {
    if ($("#SETUP_TYPE").val() == "2") { $('.YYY').attr('disabled', true); }
})

如果SETUP_TYPE为1或2,则禁用此控件。

@Html.EditorFor(model => model.CLAIM, new { htmlAttributes = new { @class = "form-control XXX YYY" } })

如果SETUP_TYPE为1,则禁用此控件。

@Html.EditorFor(model => model.POLICY, new { htmlAttributes = new { @class = "form-control XXX" } })

如果SETUP_TYPE为2,则禁用此控件。

@Html.EditorFor(model => model.INSURED, new { htmlAttributes = new { @class = "form-control YYY" } })