どのように簡潔にかみそりビューエンジンを搭載したオプションのHTML属性を作成するには?
-
25-09-2019 - |
質問
私はコード(多分5)の少ない線で次のコードを書くための方法を探しています。私は、私が選択したクラスと同じことを行うことができたとしますが、このかみそりの構文はかなり見ていないされます。
<ul>
@foreach (var mi in Model.MenuItems) {
<li@(mi.Selected?" class=\"selected\"":null)>
@if (string.IsNullOrEmpty(mi.Title)) {
<a href="@mi.Href">@mi.Text</a>
} else {
<a href="@mi.Href" title="@mi.Title">@mi.Text</a>
}
</li>
}
</ul>
解決
で修正されたASP.NET MVC 4
を参照のhttp:/ /weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspxする
の条件付き属性のレンダリングの
あなたがnullのかもしれない属性を持っている場合は、このように、空の属性を書き出す避けるために、ヌルのチェックを行うために必要なまし通り過ぎます:
<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div>
今かみそりは、あなただけの属性を書き出すことができますので、自動的にそれを処理することができます。それのnullの場合、属性が書かれていません。
<div class="@myClass">Content</div>
@myClassがnullの場合だから、出力はちょうどこの次のとおりです。
<div>Content</div>
他のヒント
私は以下のカミソリの構文を許可するように連鎖可能HtmlAttributeクラスと一部のHTML拡張メソッドを作ってみた:
<ul>
@foreach (var mi in items) {
<li @Html.Css("selected", mi.Selected)>
<a href="@mi.Href" @Html.Attr("title", mi.Title)>@mi.Text</a>
</li>
}
</ul>
ここでHtmlAttributeクラスがあります:
public class HtmlAttribute : IHtmlString
{
private string _InternalValue = String.Empty;
private string _Seperator;
public string Name { get; set; }
public string Value { get; set; }
public bool Condition { get; set; }
public HtmlAttribute(string name)
: this(name, null)
{
}
public HtmlAttribute( string name, string seperator )
{
Name = name;
_Seperator = seperator ?? " ";
}
public HtmlAttribute Add(string value)
{
return Add(value, true);
}
public HtmlAttribute Add(string value, bool condition)
{
if (!String.IsNullOrWhiteSpace(value) && condition)
_InternalValue += value + _Seperator;
return this;
}
public string ToHtmlString()
{
if (!String.IsNullOrWhiteSpace(_InternalValue))
_InternalValue = String.Format("{0}=\"{1}\"", Name, _InternalValue.Substring(0, _InternalValue.Length - _Seperator.Length));
return _InternalValue;
}
}
エクストラ情報:「区切り文字は」属性の連鎖一緒に複数の値に使用されています。これは、(スペースを使用する)複数のCSSクラス名のために有用であるか、または多分(.Add()メソッドを使用して)複数の条件に依存する値を構築するためにString.Emptyをを使用することができる
そして、ここでのHTML拡張ヘルパーメソッドです。
public static class Extensions
{
public static HtmlAttribute Css(this HtmlHelper html, string value)
{
return Css(html, value, true);
}
public static HtmlAttribute Css(this HtmlHelper html, string value, bool condition)
{
return Css(html, null, value, condition);
}
public static HtmlAttribute Css(this HtmlHelper html, string seperator, string value, bool condition)
{
return new HtmlAttribute("class", seperator).Add(value, condition);
}
public static HtmlAttribute Attr(this HtmlHelper html, string name, string value)
{
return Attr(html, name, value, true);
}
public static HtmlAttribute Attr(this HtmlHelper html, string name, string value, bool condition)
{
return Attr(html, name, null, value, condition);
}
public static HtmlAttribute Attr(this HtmlHelper html, string name, string seperator, string value, bool condition)
{
return new HtmlAttribute(name, seperator).Add(value, condition);
}
}
彼らは有用であるならば、私に教えてくださいます。
おかげで、
リー
<ul>
@foreach (var mi in Model.MenuItems) {
<li@(mi.Selected?" class=\"selected\"":null)>
<a href="@mi.Href" @{if(!string.IsNullOrEmpty(mi.Title)) { <text>title="@mi.Title"</text>} }>@mi.Text</a>
</li>
}
</ul>
私はそれをテストしていませんが、それは正しく解析します。
これは、カスタムのための良い候補になりますHTMLヘルパーます:
public static class HtmlExtensions
{
public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, MenuItem mi)
{
var li = new TagBuilder("li");
if (mi.Selected)
{
li.AddCssClass("selected");
}
var a = new TagBuilder("a");
a.MergeAttribute("href", mi.Href);
if (!string.IsNullOrEmpty(mi.Title))
{
a.MergeAttribute("title", mi.Title);
}
a.SetInnerText(mi.Text);
return MvcHtmlString.Create(li.ToString());
}
}
と、あなたのビューでます:
<ul>
@foreach (var mi in Model.MenuItems) {
@Html.MenuItem(mi)
}
</ul>
またはあなたもループを記述する必要はありませんDisplayTemplatesを使用します:
<ul>
@Html.DisplayFor(x => x.MenuItems)
</ul>
<ul>
@foreach (var mi in Model.MenuItems) {
<li@(Html.Raw((mi.Selected ? " class=\"selected\"" : null))>
<a href="@mi.Href">@mi.Text</a>
</li>
}
</ul>
class
が null
属性は、レイザーによってレンダリングされません
<a href="#nolink" class="@(categoryId == null ? "submenu-active": null)">All</a>
私はこの単純な拡張メソッドを使用して複数のクラスの場合には:
public static MvcHtmlString If(this string text, bool condition) {
return new MvcHtmlString(condition ? text : string.Empty);
}
とビューで
<div class="menuitem @("active".If(Model.Active))">
これは実際にはかなりシンプルで清潔です。
<p @(cssClass != null) ? { class="@cssClass" }> Stuff and whatnot... </p>