tutorial - Crear componentes de vista HTML reutilizables usando Razor en ASP.NET MVC
razor html (2)
Hay dos formas de lograr la funcionalidad requerida.
1. @helper
Cree @helper que acepte cualquier parámetro que necesite más una función (parámetro de objeto único, objeto de devolución):
@helper DefaultPanel(string panelTitle, Func<object, object> content)
{
<div class="panel">
<div class="panel-logo">
<img src="/logo.png" />
</div>
<div class="panel-inner">
<p class="panel-title">@panelTitle</p>
<div class="panel-content">
@content(null)
</div>
</div>
</div>
}
Uso:
@DefaultPanel("title",
@<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
)
Su función también puede aceptar parámetros, ejemplo here .
2. Método de extensión HtmlHelper
Agregue el siguiente código en cualquier lugar de su proyecto:
namespace System.Web.Mvc
{
public static class HtmlHelperExtensions
{
public static HtmlDefaultPanel DefaultPanel(this HtmlHelper html, string title)
{
html.ViewContext.Writer.Write(
"<div class=/"panel/">" +
"<div class=/"panel-inner/">" +
"<p class=/"panel-title/">" + title + "</p>" +
"<div class=/"panel-content/">"
);
return new HtmlDefaultPanel(html.ViewContext);
}
}
public class HtmlDefaultPanel : IDisposable
{
private readonly ViewContext _viewContext;
public HtmlDefaultPanel(ViewContext viewContext)
{
_viewContext = viewContext;
}
public void Dispose()
{
_viewContext.Writer.Write(
"</div>" +
"</div>" +
"</div>"
);
}
}
}
Uso:
@using (Html.DefaultPanel("title2"))
{
<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
}
El método de extensión escribe directamente en el contexto. El truco consiste en devolver un objeto desechable, cuyo método Dispose se ejecutará al final del bloque using
.
Tengo una función auxiliar Razor que crea un panel HTML reutilizable que me ahorra escribir el mismo HTML una y otra vez.
@helper DefaultPanel(string panelTitle) {
<div class="panel">
<div class="panel-logo"><img src="/logo.png"></div>
<div class=panel-inner">
<p class="panel-title">@panelTitle</p>
<div class="panel-content">
/* Can I pass content to be rendered in here here? */
</div>
</div>
</div>
</div>
}
Me pregunto si es posible volver a utilizar este .panel-content
para completar .panel-content
con más HTML para permitir una mayor flexibilidad y reutilización del código, algo similar a lo siguiente:
@LayoutHelpers.DefaultPanel("Welcome back") {
<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
}
Al usar .NET MVC, he notado que Html.BeginForm()
hace algo similar cuando se envuelve el código dentro de la declaración @using
dentro de la declaración Html.BeginForm
, así:
@using (Html.BeginForm("Index", "Login", FormMethod.Post))
{
<div>This content gets rendered within the <form></form> markup.</div>
}
Pero, ¿se puede hacer esto utilizando los métodos de @helper
? Si no es así, ¿es posible crear una extensión HtmlHelper
para hacer algo similar a como lo hace el método Html.BeginForm()
?
Puedes hacer algo muy similar usando la sintaxis @section
como se ve here
Esto parece algo que sería realmente útil para poder hacer, y es extraño que no haya una manera fácil de hacerlo en un nivel de componente.
No sé si los métodos de @helper
pueden hacer esto, pero HtmlHelper
extensiones de HtmlHelper
sí pueden hacerlo. Mencionó el ejemplo Html.BeginForm()
que probablemente sea el más conocido, lo único que hace es devolver un objeto que implemente IDisposable
que significa que cuando se llama al método Dispose()
simplemente llama al Html.EndForm()
complementario método para agregar las etiquetas de cierre apropiadas.
Sería muy simple hacer algo similar para su código HTML. Puede ver el código fuente en ASP.NET MVC HtmlHelpers en http://aspnetwebstack.codeplex.com/ - el código BeginForm()
puede ver específicamente aquí .