ASP.NET MVC бритва: условный атрибут в HTML
Код ниже не кажется чистым.
Любое предложение улучшить код?
<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>
Ответы
Ответ 1
MVC имеет встроенные условные атрибуты...
<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div>
<div class="@myClass">Content</div>
Если @myClass равен нулю, он просто не будет использовать атрибут вообще...
Я знаю, что это может не совсем решить вашу текущую проблему, но это заслуживает внимания!
http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx
Ответ 2
<li class="@(ViewBag.pagename == "Business details" ? "active" : null)">
Вы должны заменить inline style="..."
отдельным именем класса и использовать там тот же синтаксис.
Однако было бы проще сделать отдельный метод расширения HTML-помощника, который будет принимать имя страницы и действия и генерирует HTML в целом.
Ответ 3
Я использую небольшой вспомогательный метод, который условно добавит атрибут, если значение не пустое, и, если определено, когда выражение булевой функции оценивается как 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
.
Ответ 4
В 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/
Ответ 5
Подход с использованием метода расширения 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
использование Microsoft.AspNetCore.Mvc.ViewFeatures;
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();
}
}
Ответ 6
Основываясь на размораживаниях, ответьте здесь на адаптацию, взяв 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;
}
Таким образом, вам не нужно превращать другие типы данных в строки перед их передачей, сохраняя fiew .ToString()
. Существует различие: прохождение пустой строки все равно будет отображаться. Как пример:
@Html.ConditionalAttr("data-foo", "", () => Model.IsFooNeeded)
// Ouput:
data-foo=""