Как кратко создавать дополнительные HTML-атрибуты с помощью Razor View Engine?

StackOverflow https://stackoverflow.com/questions/3800473

  •  25-09-2019
  •  | 
  •  

Вопрос

Я ищу способ написать следующий код с меньшими строками кода (может быть 5). Я полагаю, что я мог бы сделать то же самое, что и выбранный класс, но этот синтаксис бритвы не выглядит красиво.

<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>
Это было полезно?

Решение

Исправлено в ASP.NET MVC 4

видеть http://weblogs.ass.asp.net/jgalloway/Archive/2012/02/16/asp-net-4-beta-relende.aspx.

Условный атрибут рендеринг

Если у вас есть атрибут, который может быть NULL, в прошлом вам нужно сделать нуль, чтобы избежать записи пустого атрибута, как это:

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

Теперь бритва может обрабатывать это автоматически, так что вы можете просто выписать атрибут. Если это ноль, атрибут не написан:

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

Так что, если @myclass нуль, вывод просто это:

<div>Content</div>

Другие советы

Я придумал цепочтимый класс HTMLATTribute и некоторыми методами расширения HTML, чтобы позволить синтаксис бритвы ниже:

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

Вот класс 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;
    }
}

Дополнительная информация: «Seperator» используется для объединения нескольких значений для атрибута. Это может быть полезно для нескольких имен классов CSS (используйте пробел) или, возможно, используйте String.empty для создания значения, зависящего от нескольких условий (с помощью метода .add ())

И вот в HTML-расширении помощника помощников:

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

Дайте мне знать, если они используют.

Спасибо,

Ли

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

Я не проверил его, но он правильно разобран.

Это был бы хороший кандидат на заказ HTML-помощник:

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

И по вашему мнению:

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

Или использовать DisplayTemplates, вам даже не нужно писать цикл:

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

class атрибут не будет отображаться бритвой, если значение null

<a href="#nolink" class="@(categoryId == null ? "submenu-active": null)">All</a>

Для случая нескольких классов я использую этот простой метод расширения:

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

И по мнению:

<div class="menuitem @("active".If(Model.Active))">

Это действительно довольно просто и чисто:

<p @(cssClass != null) ? { class="@cssClass" }> Stuff and whatnot... </p>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top