El siguiente código no parece limpio. ¿Alguna sugerencia para mejorar el código?
<li @if(ViewData["pagename"].ToString()=="Business details"){ <text>class="active" </text> } >
<a @if(ViewData["pagename"].ToString()=="Business details"){ <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> }
href="@Url.Action("BusinessDetails", "Business")">Business Details</a>
</li>
<li @if (ViewData["pagename"].ToString() == "Booking policies"){ <text>class="active"</text> }>
<a @if (ViewData["pagename"].ToString() == "Booking policies")
{ <text>style="color: white; background-color: #08C; border: 1px solid #08C;" </text> }
href="@Url.Action("BookingPolicies", "Business")">Booking policies</a>
</li>
asp.net-mvc
asp.net-mvc-3
razor
Mahesh
fuente
fuente
Respuestas:
MVC tiene atributos condicionales integrados ...
<div @{if (myClass != null) { <text>class="@myClass"</text> } }>Content</div> <div class="@myClass">Content</div>
Si @myClass es nulo, simplemente no usará el atributo en absoluto ...
Sé que puede que no resuelva del todo su problema actual, ¡pero es digno de mención!
http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx
fuente
htmlProperties
objeto anónimo ? Por ejemplo, quiero pasar un atributo condicionalmentedisabled
, como@Html.TextBoxFor(lambda, new { disabled = condition ? true : null })
, pero que aún se muestradisabled=""
cuandodisabled
estabanull
, que es lo mismo que reproducirdisabled="anything"
porquedisabled
está activo cuando el atributo está presente, independientemente del valor. Encontré stackoverflow.com/q/7978137/11683 sobre el tema, pero me pregunto si hay mejores formas hoy en día.<li class="@(ViewBag.pagename == "Business details" ? "active" : null)">
Debe reemplazar el en línea
style="..."
con un nombre de clase separado y usar la misma sintaxis allí.Sin embargo, sería más limpio crear un método de extensión auxiliar HTML separado que tome un nombre de página y acción y genere el HTML de forma genérica.
fuente
Utilizo un pequeño método auxiliar que agregará condicionalmente un atributo si el valor no está vacío y, si está definido, cuando una expresión de función booleana se evalúa como
true
:public static MvcHtmlString Attr(this HtmlHelper helper, string name, string value, Func<bool> condition = null) { if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString(string.Format("{0}=\"{1}\"", name, HttpUtility.HtmlAttributeEncode(value))) : MvcHtmlString.Empty; }
Una vez definido, puedo usar este método en mis vistas de Razor:
<li @(Html.Attr("class", "new", () => example.isNew))> ... </li>
El código anterior se mostrará
<li class="new">...</li>
siexample.isNew == true
, de lo contrario, se omitirá todo elclass
atributo.fuente
Func<bool>
lambda, preferiré unbool?
parámetro simple , porque es más simple:<li @Html.Attr("class", "new", example.isNew)>
En MVC4
<!DOCTYPE html> <html> <head> </head> <body> @{ string css = "myDiv"; } <div class='@css'></div> </body> </html>
o
<!DOCTYPE html> <html> <head> </head> <body> @{ string css = "class=myDiv"; } <div @css></div> </body> </html>
Hay más aquí: http://evolpin.wordpress.com/2012/05/20/mvc-4-code-enhancements/
fuente
Aproximación con el método de extensión TagWrap. El código para su pregunta se vería así:
@using (Html.TagWrap("li", condition ? new { @class = "active" } : null)) { var anchorAttrs = new Dictionary<string, object> { { "href", Url.Action("BusinessDetails", "Business") } }; if(condition) { anchorAttrs["style"] = "color: white; background-color: #08C; border: 1px solid #08C;"; } using (Html.TagWrap("a", anchorAttrs)) { <text>Business Details</text> } }
Métodos de extensión TagWrap
public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, object data) { return htmlHelper.TagWrap(tagName, HtmlHelper.AnonymousObjectToHtmlAttributes(data)); } public static IDisposable TagWrap(this IHtmlHelper htmlHelper, string tagName, IDictionary<string, object> data) { var tag = new TagBuilder(tagName); tag.MergeAttributes(data); htmlHelper.ViewContext.Writer.Write(tag.RenderStartTag()); return new DisposableAction(() => htmlHelper.ViewContext.Writer.Write(tag.RenderEndTag())); }
Clase auxiliar utilizada para representar la etiqueta de cierre en Dispose
public class DisposableAction : IDisposable { private readonly Action DisposeAction; public DisposableAction(Action action) { DisposeAction = action; } public void Dispose() { DisposeAction(); } }
fuente
Basado en desescarches, responda aquí una adaptación, tomando un en
object
lugar de unstring
:public static MvcHtmlString ConditionalAttr(this HtmlHelper helper, string attributeName, object value, Func<bool> condition) { if (string.IsNullOrEmpty(attributeName) || value == null) { return MvcHtmlString.Empty; } var render = condition != null ? condition() : true; return render ? new MvcHtmlString($"{attributeName}=\"{HttpUtility.HtmlAttributeEncode(value.ToString())}\"") : MvcHtmlString.Empty; }
De esta manera, no tiene que convertir sus otros tipos de datos en cadenas antes de pasarlos, guardando una vista
.ToString()
. Sin embargo, hay una diferencia : pasar una cadena vacía aún se procesará. Como ejemplo:@Html.ConditionalAttr("data-foo", "", () => Model.IsFooNeeded) // Ouput: data-foo=""
fuente
@{ var classAttr= needClass ? "class=\"class-name\"" : "" }
y luego en el HTML
fuente