Код ниже не кажется чистым. Есть предложения по улучшению кода?
<li @if(ViewData["pagename"].ToString()=="Business details"){ <text>class="active" </text> } >
<a @if(ViewData["pagename"].ToString()=="Business details"){ <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> }
href="@Url.Action("BusinessDetails", "Business")">Business Details</a>
</li>
<li @if (ViewData["pagename"].ToString() == "Booking policies"){ <text>class="active"</text> }>
<a @if (ViewData["pagename"].ToString() == "Booking policies")
{ <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> }
href="@Url.Action("BookingPolicies", "Business")">Booking policies</a>
</li>
Ответы:
MVC имеет встроенные условные атрибуты ...
<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div> <div class="@myClass">Content</div>
Если @myClass имеет значение null, он просто не будет использовать атрибут вообще ...
Я знаю, что это может не совсем решить вашу текущую проблему, но это заслуживает внимания!
http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx
источник
htmlProperties
объект? Например, я хочу условно передать атрибутdisabled
, например@Html.TextBoxFor(lambda, new { disabled = condition ? true : null })
, но он все равно отображается,disabled=""
когдаdisabled
былnull
, что аналогично воспроизведению,disabled="anything"
потому чтоdisabled
он активен, когда атрибут присутствует, независимо от значения. Нашел stackoverflow.com/q/7978137/11683 по теме, но есть ли в настоящее время способы лучше?<li class="@(ViewBag.pagename == "Business details" ? "active" : null)">
Вы должны заменить inline
style="..."
отдельным именем класса и использовать там тот же синтаксис.Однако было бы проще создать отдельный вспомогательный метод расширения HTML, который принимает имя страницы и действия и генерирует HTML в общем виде.
источник
Я использую небольшой вспомогательный метод, который условно добавляет атрибут, если значение не пустое, и, если определено, когда выражение логической функции оценивается как
true
:public static MvcHtmlString Attr(this HtmlHelper helper, string name, string value, Func<bool> condition = null) { if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString(string.Format("{0}=\"{1}\"", name, HttpUtility.HtmlAttributeEncode(value))) : MvcHtmlString.Empty; }
После определения я могу использовать этот метод в представлениях Razor:
<li @(Html.Attr("class", "new", () => example.isNew))> ... </li>
Приведенный выше код будет оказывать ,
<li class="new">...</li>
еслиexample.isNew == true
, если не будет опускать весьclass
атрибут.источник
Func<bool>
лямбды я предпочту простойbool?
параметр, потому что он проще:<li @Html.Attr("class", "new", example.isNew)>
В MVC4
<!DOCTYPE html> <html> <head> </head> <body> @{ string css = "myDiv"; } <div class='@css'></div> </body> </html>
или же
<!DOCTYPE html> <html> <head> </head> <body> @{ string css = "class=myDiv"; } <div @css></div> </body> </html>
Больше здесь: http://evolpin.wordpress.com/2012/05/20/mvc-4-code-enhancements/
источник
Подход с использованием метода расширения TagWrap. Код для вашего вопроса будет выглядеть так:
@using (Html.TagWrap("li", condition ? new { @class = "active" } : null)) { var anchorAttrs = new Dictionary<string, object> { { "href", Url.Action("BusinessDetails", "Business") } }; if(condition) { anchorAttrs["style"] = "color: white; background-color: #08C; border: 1px solid #08C;"; } using (Html.TagWrap("a", anchorAttrs)) { <text>Business Details</text> } }
Методы расширения TagWrap
public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, object data) { return htmlHelper.TagWrap(tagName, HtmlHelper.AnonymousObjectToHtmlAttributes(data)); } public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, IDictionary<string, object> data) { var tag = new TagBuilder(tagName); tag.MergeAttributes(data); htmlHelper.ViewContext.Writer.Write(tag.RenderStartTag()); return new DisposableAction(() => htmlHelper.ViewContext.Writer.Write(tag.RenderEndTag())); }
Вспомогательный класс, используемый для отображения закрывающего тега в Dispose
public class DisposableAction : IDisposable { private readonly Action DisposeAction; public DisposableAction(Action action) { DisposeAction = action; } public void Dispose() { DisposeAction(); } }
источник
На основе размораживания ответьте здесь на адаптацию, взяв
object
вместоstring
:public static MvcHtmlString ConditionalAttr(this HtmlHelper helper, string attributeName, object value, Func<bool> condition) { if (string.IsNullOrEmpty(attributeName) || value == null) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString($"{attributeName}=\"{HttpUtility.HtmlAttributeEncode(value.ToString())}\"") : MvcHtmlString.Empty; }
Таким образом, вам не нужно превращать другие типы данных в строки перед их передачей, что экономит время
.ToString()
. Есть разница : передача пустой строки все равно будет отображаться. Например:@Html.ConditionalAttr("data-foo", "", () => Model.IsFooNeeded) // Ouput: data-foo=""
источник
@{ var classAttr= needClass ? "class=\"class-name\"" : "" }
а затем в HTML
источник