Как кратко создать необязательные атрибуты HTML с помощью бритвенного движка? - PullRequest
39 голосов
/ 27 сентября 2010

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

Ответы [ 8 ]

51 голосов
/ 02 марта 2012

Исправлено в 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 может обрабатывать это автоматически, поэтому вы можете просто выписать атрибут. Если он нулевой, атрибут не записывается:

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

Так что, если @myClass имеет значение null, результат будет следующим:

<div>Content</div>
41 голосов
/ 20 ноября 2010

Я разработал цепочечный класс 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:

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

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

Спасибо

Lee

10 голосов
/ 27 сентября 2010
<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>

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

7 голосов
/ 27 сентября 2010

Это было бы хорошим кандидатом для пользовательского помощника 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>
4 голосов
/ 30 марта 2011
<ul>
@foreach (var mi in Model.MenuItems) {
  <li@(Html.Raw((mi.Selected ? " class=\"selected\"" : null))>
    <a href="@mi.Href">@mi.Text</a>
  </li>
}
</ul>
3 голосов
/ 26 сентября 2013

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

<a href="#nolink" class="@(categoryId == null ? "submenu-active": null)">All</a>
1 голос
/ 12 ноября 2014

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

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

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

<div class="menuitem @("active".If(Model.Active))">
0 голосов
/ 21 апреля 2011

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

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