Подтвердить что ты не робот

Как сжато создавать дополнительные атрибуты HTML с движком просмотра бритвы?

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

<ul>
@foreach (var mi in Model.MenuItems) {
  <[email protected](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>
4b9b3361

Ответ 1

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

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

Предоставление условного атрибута

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

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

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

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

Итак, если @myClass имеет значение NULL, вывод будет следующим:

<div>Content</div>

Ответ 2

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

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

Дополнительная информация: "Сепаратор" используется для объединения нескольких значений атрибута. Это может быть полезно для нескольких имен класса css (используйте пробел) или, возможно, используйте String.Empty для создания значения, зависящего от нескольких условий (с помощью метода .Add())

И вот вспомогательные методы 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);
    }
}

Сообщите мне, если они полезны.

Спасибо,

Ли

Ответ 3

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

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

Ответ 4

Это будет хорошим кандидатом для пользовательского 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>

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

И в представлении:

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

Ответ 9

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

<p @(cssClass != null) ? { class="@cssClass" }> Stuff and whatnot... </p>