我有这行代码:
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } })
我的视图数据字典中有一个名为 Readonly 的变量。如何在
ViewBag.Readonly
为 true 时使 Quantity 只读,而仅在为 false 时不只读?
简单的事情,但是 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" } })
编辑: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" } })
今天我必须处理这个问题,因为我必须动态地为
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))
代码非常不言自明,但是我还在我的博客上的这篇文章中解释了底层逻辑。
非常简单。这样做。
@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" } })
}
如果你的视图中有很多地方都有这样的逻辑,我认为使用库FluentDataAnnotations可以让你的代码干净整洁。
如果您熟悉FluentValidator,那么使用起来非常相似。
在您的情况下,所有逻辑都将从视图移动到模型注释类。你只会拥有
@Html.EditorFor(model => model.Quantity)
它甚至允许在条件下使用模型属性 例如
this.When(model => !model.AllowEditPhone,
() => {
this.For(m => m.Phone).SetReadOnly(false);
});
这里是需要 ASP.NET MVC 5 的 NuGet 包。 (对 ASP.NET Core 的支持正在进行中。)
通过编写辅助方法,可以尊重 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*/)
然后您可以添加您想要的任何其他覆盖。
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" } })
您可以编写带有附加参数的 IHtmlHelper 扩展:
public static IHtmlContent ReadonlyishTextBoxFor<TModel, TProperty>(this IHtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null, bool shouldBeReadonly = false)
{
var attributes = new Dictionary<string, object>();
if (htmlAttributes != null)
{
foreach (var propertyInfo in htmlAttributes.GetType().GetProperties())
{
attributes.Add(propertyInfo.Name, propertyInfo.GetValue(htmlAttributes));
}
}
if (shouldBeReadonly)
{
attributes.Add("readonly", "readonly");
}
return helper.TextBoxFor(expression, format: null, attributes);
}
剃须刀:
@Html.ReadonlyishTextBoxFor(p => p.Email, new { @class = "form-control" }, true )
@Html.ReadonlyishTextBoxFor(p => p.Email, new { @class = "form-control" } )
老问题,但今天正在看这个 - 所以我想无论如何都会添加一个答案。
html 助手接受 html 属性作为对象或 IDictionary
这意味着我们可以添加代码来构造变量的属性,然后将其传入。
例如
@{
var htmlAttributes = new Dictionary<string, object>()
{
{ "@class", "form-control" }
};
if (ViewBag.Readonly) htmlAttributes.Add("@readonly", "readonly");
}
@Html.EditorFor(model => model.Quantity, new { htmlAttributes = htmlAttributes })