ASP.NET MVC razor: условный атрибут в 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> 
5 59

5 ответов:

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

<li class="@(ViewBag.pagename == "Business details" ? "active" : null)">  

вы должны заменить рядный 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, если не опущу весь

в 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

С помощью 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();
    }
}