40 votes

Comment créer de manière concise des attributs HTML optionnels avec le moteur de vue de Razor ?

Je cherche un moyen d'écrire le code suivant avec moins de lignes de code (peut-être 5). Je suppose que je pourrais faire la même chose que la classe sélectionnée mais cette syntaxe de rasoir n'est pas très jolie.

<ul>
@foreach (var mi in Model.MenuItems) {
  <li@(mi.Selected?" class=\"selected\"":null)>
  @if (string.IsNullOrEmpty(mi.Title)) {
    <a href="@mi.Href">@mi.Text</a>
  } else {
    <a href="@mi.Href" title="@mi.Title">@mi.Text</a>
  }
  </li>
}
</ul>

53voto

JarrettV Points 9099

Corrigé dans ASP.NET MVC 4

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

Rendu conditionnel des attributs

Si vous avez un attribut qui peut être nul, vous deviez auparavant effectuer un contrôle de nullité pour éviter d'écrire un attribut vide, comme ceci :

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

Maintenant, Razor est capable de gérer cela automatiquement, de sorte que vous pouvez simplement écrire l'attribut. S'il est nul, l'attribut n'est pas écrit :

<div class="@myClass">Content</div>

Donc si @myClass est null, la sortie est juste ceci :

<div>Content</div>

41voto

Lee Gunn Points 3178

J'ai créé une classe HtmlAttribute chaînable et quelques méthodes Html Extension pour permettre la syntaxe Razor ci-dessous :

<ul> 
    @foreach (var mi in items) { 
    <li @Html.Css("selected", mi.Selected)> 
        <a href="@mi.Href" @Html.Attr("title", mi.Title)>@mi.Text</a> 
    </li> 
    } 
</ul> 

Voici la classe HtmlAttribute :

public class HtmlAttribute : IHtmlString     
{
    private string _InternalValue = String.Empty;
    private string _Seperator;

    public string Name { get; set; }
    public string Value { get; set; }
    public bool Condition { get; set; }

    public HtmlAttribute(string name)
        : this(name, null)
    {
    }

    public HtmlAttribute( string name, string seperator )
    {
        Name = name;
        _Seperator = seperator ?? " ";
    }

    public HtmlAttribute Add(string value)
    {
        return Add(value, true);
    }

    public HtmlAttribute Add(string value, bool condition)
    {
        if (!String.IsNullOrWhiteSpace(value) && condition)
            _InternalValue += value + _Seperator;

        return this;
    }

    public string ToHtmlString()
    {
        if (!String.IsNullOrWhiteSpace(_InternalValue))
            _InternalValue = String.Format("{0}=\"{1}\"", Name, _InternalValue.Substring(0, _InternalValue.Length - _Seperator.Length));
        return _InternalValue;
    }
}

Informations supplémentaires : Le "seperator" est utilisé pour enchaîner plusieurs valeurs pour un attribut. Cela peut être utile pour plusieurs noms de classes css (utilisez un espace) ou peut-être utiliser String.Empty pour construire une valeur dépendant de plusieurs conditions (en utilisant la méthode .Add()).

Et voici les méthodes d'aide de Html Extension :

public static class Extensions
{
    public static HtmlAttribute Css(this HtmlHelper html, string value)
    {
        return Css(html, value, true);
    }

    public static HtmlAttribute Css(this HtmlHelper html, string value, bool condition)
    {
        return Css(html, null, value, condition);
    }

    public static HtmlAttribute Css(this HtmlHelper html, string seperator, string value, bool condition)
    {
        return new HtmlAttribute("class", seperator).Add(value, condition);
    }

    public static HtmlAttribute Attr(this HtmlHelper html, string name, string value)
    {
        return Attr(html, name, value, true);
    }

    public static HtmlAttribute Attr(this HtmlHelper html, string name, string value, bool condition)
    {
        return Attr(html, name, null, value, condition);
    }

    public static HtmlAttribute Attr(this HtmlHelper html, string name, string seperator, string value, bool condition)
    {
        return new HtmlAttribute(name, seperator).Add(value, condition);
    }
}

Faites-moi savoir si elles vous sont utiles.

Merci,

Lee

10voto

BuildStarted Points 15931
<ul>
@foreach (var mi in Model.MenuItems) {
    <li@(mi.Selected?" class=\"selected\"":null)>
        <a href="@mi.Href" @{if(!string.IsNullOrEmpty(mi.Title)) { <text>title="@mi.Title"</text>} }>@mi.Text</a>
    </li>
}
</ul>

Je ne l'ai pas testé mais il est correctement analysé.

7voto

Darin Dimitrov Points 528142

Ce serait un bon candidat pour une aide HTML personnalisée :

public static class HtmlExtensions
{
    public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, MenuItem mi)
    {
        var li = new TagBuilder("li");
        if (mi.Selected)
        {
            li.AddCssClass("selected");
        }
        var a = new TagBuilder("a");
        a.MergeAttribute("href", mi.Href);
        if (!string.IsNullOrEmpty(mi.Title))
        {
            a.MergeAttribute("title", mi.Title);
        }
        a.SetInnerText(mi.Text);
        return MvcHtmlString.Create(li.ToString());
    }
}

et dans votre vue :

<ul>
@foreach (var mi in Model.MenuItems) {
    @Html.MenuItem(mi)
}
</ul>

ou en utilisant DisplayTemplates, vous n'avez même pas besoin d'écrire une boucle :

<ul>
    @Html.DisplayFor(x => x.MenuItems)
</ul>

4voto

Konstantin Tarkus Points 16862
<ul>
@foreach (var mi in Model.MenuItems) {
  <li@(Html.Raw((mi.Selected ? " class=\"selected\"" : null))>
    <a href="@mi.Href">@mi.Text</a>
  </li>
}
</ul>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X