web-dev-qa-db-fra.com

ASP.NET MVC razor: attribut conditionnel en HTML

Le code ci-dessous ne semble pas être propre .. Une suggestion pour améliorer le code?

<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 a des attributs conditionnels intégrés dans ...

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

Si @myClass est null, il n'utilisera pas l'attribut du tout ...

Je sais que cela ne résoud peut-être pas tout à fait votre problème actuel, mais il est à noter!

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)">  

Vous devez remplacer le style="..." en ligne par un nom de classe séparé et utiliser la même syntaxe.

Cependant, il serait plus propre de créer une méthode d’extension d’assistant HTML distinct qui prend un nom de page et d’action et génère le code HTML de manière générique.

64
SLaks

J'utilise une petite méthode d'assistance qui ajoute conditionnellement un attribut si la valeur n'est pas vide et, si elle est définie, lorsqu'une expression de fonction booléenne est évaluée à 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;
}

Une fois définie, je peux utiliser cette méthode dans mes vues Razor:

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

Le code ci-dessus rendra <li class="new">...</li> si example.isNew == true, sinon omettra l'attribut class complet.

18
defrost

Dans MVC4 

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

ou

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

Plus sont ici: http://evolpin.wordpress.com/2012/05/20/mvc-4-code-enhancements/

2
David Slavík

Approche avec la méthode d'extension TagWrap. Le code de votre question ressemblerait à ceci:

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

Méthodes d'extension TagWrap 

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

Classe d'assistance utilisée pour le rendu de la balise de fermeture dans Dispose

public class DisposableAction : IDisposable
{
    private readonly Action DisposeAction;

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

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

Sur la base des dégivrages, répondez ici à une adaptation en prenant une object au lieu d'une 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;
    }

Ainsi, vous n'avez pas besoin de transformer vos autres types de données en chaînes avant de les transmettre, en enregistrant un fiew .ToString(). Il y a une différence entre : passer une chaîne vide restituera toujours. À titre d'exemple:

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

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