How to concisely create optional HTML attributes w

2019-01-31 06:42发布

I'm looking for a way to write the following code with less lines of code (maybe 5). I suppose I could do the same thing as the selected class but this razor syntax isn't looking pretty.

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

8条回答
▲ chillily
2楼-- · 2019-01-31 07:26

That would be a good candidate for custom HTML helper:

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

and in your view:

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

or using DisplayTemplates you don't even need to write a loop:

<ul>
    @Html.DisplayFor(x => x.MenuItems)
</ul>
查看更多
smile是对你的礼貌
3楼-- · 2019-01-31 07:29

For the case of multiple classes I use this simple extension method:

public static MvcHtmlString If(this string text, bool condition) {
    return new MvcHtmlString(condition ? text : string.Empty);
}

And in the view:

<div class="menuitem @("active".If(Model.Active))">
查看更多
登录 后发表回答