wake-up-neo.net

ASP.NET MVC-Rasierer: Bedingtes Attribut in HTML

Der folgende Code scheint nicht sauber zu sein.

<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> 
65
Mahesh

MVC verfügt über bedingte Attribute, die in ...

<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div>
<div class="@myClass">Content</div>

Wenn @myClass den Wert null hat, wird das Attribut überhaupt nicht verwendet ...

Ich weiß, dass Ihr aktuelles Problem möglicherweise nicht ganz gelöst wird, aber es ist bemerkenswert!

http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx

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

Sie sollten den Inlinecode style="..." durch einen separaten Klassennamen ersetzen und dort dieselbe Syntax verwenden.

Es wäre jedoch einfacher, eine separate HTML-Helper-Erweiterungsmethode zu erstellen, die einen Seiten- und Aktionsnamen übernimmt und den HTML-Code generisch generiert.

64
SLaks

Ich verwende eine kleine Hilfsmethode, die ein Attribut bedingt hinzufügt, wenn der Wert nicht leer ist, und wenn definiert, wenn ein boolescher Funktionsausdruck zu true ausgewertet wird:

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;
}

Einmal definiert, kann ich diese Methode in meinen Razor-Ansichten verwenden:

<li @(Html.Attr("class", "new", () => example.isNew))>
...
</li>

Der obige Code wird <li class="new">...</li> wiedergeben, wenn example.isNew == true, falls nicht, das gesamte class-Attribut weggelassen wird.

18
defrost

In MVC4 

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "myDiv";
    }
    <div class='@css'></div>
</body>
</html>

oder

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    @{
        string css = "class=myDiv";
    }
    <div @css></div>
</body>
</html>

Weitere sind hier: http://evolpin.wordpress.com/2012/05/20/mvc-4-code-enhancements/

2
David Slavík

Ansatz mit der Erweiterungsmethode TagWrap. Code für Ihre Frage würde so aussehen:

@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-Erweiterungsmethoden 

using 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()));
}

Hilfsklasse, die zum Rendern des schließenden Tags bei Dispose verwendet wird

public class DisposableAction : IDisposable
{
    private readonly Action DisposeAction;

    public DisposableAction(Action action)
    {
        DisposeAction = action;
    }

    public void Dispose()
    {
        DisposeAction();
    }
}
0
Pavlo Neyman

Basierend auf Abtauungen hier eine Anpassung beantworten, wobei eine object anstelle einer string verwendet wird:

    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;
    }

Auf diese Weise müssen Sie Ihre anderen Datentypen nicht in Zeichenfolgen umwandeln, bevor Sie sie übergeben. Dadurch wird eine Ansicht .ToString() gespeichert. Es gibt einen Unterschied zu : Übergeben einer leeren Zeichenfolge wird immer noch gerendert. Zum Beispiel:

@Html.ConditionalAttr("data-foo", "", () => Model.IsFooNeeded)

// Ouput:
data-foo=""
0
spaark