html 属性をディクショナリとして返すヘルパーを作成しました。これは、ヘルパーが属性をレンダリングするために使用されます。
その後、属性は一部の JavaScript コードで使用されます。
コードは重要ではありませんが、ここにあります
namespace MvcHtmlHelpers
{
public class PropertyValuePairs<TModel>
{
public readonly IDictionary<string, object> Pairs = new Dictionary<string, object>();
private HtmlHelper<TModel> _html;
public PropertyValuePairs(HtmlHelper<TModel> html)
{
_html=html;
}
public PropertyValuePairs<TModel> AddNameFor<TValue>(Expression<Func<TModel, TValue>> expression, object value)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
string name = _html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);
return AddName(name, value);
}
public PropertyValuePairs<TModel> AddName(string name, object value)
{
Pairs.Add(name, value);
return this;
}
public PropertyValuePairs<TModel> AddIdFor<TValue>(Expression<Func<TModel, TValue>> expression, object value)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
string id = _html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName);
return AddName(id, value);
}
public PropertyValuePairs<TModel> AddId(string id, object value)
{
Pairs.Add('#' + id, value);
return this;
}
}
public enum LogicalOperator { And, Or }
public static class EnabledIfAttributes
{
public static PropertyValuePairs<TModel> NewPropertyValues<TModel>(this HtmlHelper<TModel> html)
{
return new PropertyValuePairs<TModel>(html);
}
//for use in javaScript - lower case property names are intentional
public class PropertyPair
{
public string name { get; set; }
public object val { get; set; }
}
public class dataAttribute
{
public string logicalOperator { get; set; }
public List<PropertyPair> propertyPairs { get; set; }
}
public const string ClassName = "enabledif";
public static string AttributeName = "data-" + ClassName;
public static IDictionary<string, object> EnabledIfAttributesFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object value)
{
return EnabledIfAttributesFor(html, expression, value, new RouteValueDictionary());
}
public static IDictionary<string, object> EnabledIfAttributesFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object value, object htmlAttributes)
{
return EnabledIfAttributesFor(html, expression, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static IDictionary<string, object> EnabledIfAttributesFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object value, IDictionary<string, object> htmlAttributes)
{
var pairList = new PropertyValuePairs<TModel>(html).AddNameFor(expression, value);
return EnabledIfAttributesFor(html, pairList, new RouteValueDictionary(htmlAttributes));
}
public static IDictionary<string, object> EnabledIfAttributesFor<TModel>(this HtmlHelper<TModel> html, PropertyValuePairs<TModel> values, LogicalOperator logicalOperator = LogicalOperator.Or)
{
return EnabledIfAttributesFor(html, values, new RouteValueDictionary(), logicalOperator);
}
public static IDictionary<string, object> EnabledIfAttributesFor<TModel>(this HtmlHelper<TModel> html, PropertyValuePairs<TModel> values, object htmlAttributes, LogicalOperator logicalOperator = LogicalOperator.Or)
{
return EnabledIfAttributesFor(html, values, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), logicalOperator);
}
public static IDictionary<string, object> EnabledIfAttributesFor<TModel>(this HtmlHelper<TModel> html, PropertyValuePairs<TModel> values, IDictionary<string, object> htmlAttributes, LogicalOperator logicalOperator = LogicalOperator.Or)
{
//in this case expression refers to other property
if (htmlAttributes.ContainsKey("class"))
{
string existingClass = htmlAttributes["class"].ToString().Trim();
htmlAttributes["class"] = existingClass + ' ' + ClassName;
}
else
{
htmlAttributes.Add("class",ClassName);
}
var attr = new dataAttribute
{
logicalOperator = logicalOperator.ToString(),
propertyPairs = new List<PropertyPair>()
};
foreach (var pair in values.Pairs)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(pair.Key);
attr.propertyPairs.Add(new PropertyPair
{
name = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName),
val = pair.Value
});
}
htmlAttributes.Add(AttributeName, JsonConvert.SerializeObject(attr));
return htmlAttributes;
}
}
}
次のようなコードで使用されます
@Html.CheckBoxFor(model => model.AllExclusionCriteriaAbsent, @Html.EnabledIfAttributesFor(model=>model.AllInclusionCriteriaPresent, true))
同じ属性を <div></div> に追加したいと思います。つまり、ヘルパーはありません。divヘルパーを書くのはばかげているので、辞書をhtml属性としてレンダリングする既存の方法があるかどうか(MVCに付属するすべてのヘルパーで使用される方法が必要です)、またはきれいに/簡潔に行う方法があるかどうか疑問に思っていましたこれはかみそり2で。ありがとう。
編集
ロスの提案を使用すると、これにアプローチするには2つの簡単な方法があるようです:
namespace MvcHtmlHelpers
{
public static class SimpleTagHelper
{
public static MvcHtmlString Element(string tagName, IDictionary<string, object> attributes, TagRenderMode renderMode=TagRenderMode.Normal)
{
var tag = new TagBuilder(tagName);
tag.MergeAttributes(attributes);
return MvcHtmlString.Create(tag.ToString(renderMode));
}
public static MvcHtmlString ToAttributes(this IDictionary<string, object> attributeDictionary)
{
return MvcHtmlString.Create(string.Join(" ",attributeDictionary.Select(d=>string.Format("{0}=\"{1}\"",d.Key,HttpUtility.HtmlAttributeEncode(d.Value.ToString())))));
}
}
}
次に、好みのセマンティクスを選択します。
@SimpleTagHelper.Element("div", Html.EnabledIfAttributesFor(model => model.AllExclusionCriteriaAbsent, true, new { @class="optionList"}), TagRenderMode.StartTag)
また
<div @Html.EnabledIfAttributesFor(model => model.AllExclusionCriteriaAbsent, true, new { @class="optionList"}).ToAttributes() >