2010-09-27 5 views
36

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

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

Последняя версия бритвой в настоящее время имеет встроенную поддержку для этого. См. Ответ ниже. – JarrettV

ответ

46

исправленные в 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 равно нулю, то выход только это:

<div>Content</div> 
+6

Вы на самом деле не имеете в виду ASP.NET 4, вы имеете в виду ASP.NET * MVC * 4, который на момент написания еще находится в бета-версии - ASP.NET 4 поставляется с VS2010 и .NET 4.0 и не содержит условного атрибута , –

+1

Как это сделать, если я хочу добавить стиль в другие стили. Скажем, если значение bool истинно, например, 'display: none'. Или мне еще нужно использовать эту уродливую условность? – ppumkin

+0

Хороший ответ, отлично работает! –

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

много simpiler необязательные атрибуты HTML я не проверял, но это правильно разбирает.

+0

Это не работает – JarrettV

+2

Ничего себе, если бы вы нашли время взглянуть на сообщение об ошибке, которое вы бы увидели, что все, что вам нужно было сделать, это добавить {} вокруг содержимого блока if, и вы бы увидели, что мой код производит точный вывод вы искали ... – Buildstarted

+0

Yikes, я «посмотрел» на сообщение об ошибке и попробовал скобки, но я не должен был понимать сообщение. :) Спасибо за обновление вашего сообщения. – JarrettV

7

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

Дарин, ваш код замечательный, но почему-то я чувствую, что это побеждает цель бритвы. Microsoft должна решить эту проблему. – JarrettV

40

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

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

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

Спасибо,

Ли

+1

Вам нужно избежать значений. – SLaks

+0

Привет, Ли, вы можете дать мне понять, где разместить эти классы в проекте MVC, и как/где ссылаться на них? –

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

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

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

Недействительно. –

2

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

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

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^