martes, 26 de junio de 2018
Con ASP.NET MVC 5 y anteriores solíamos utilizar
Recordaréis que esta directiva permitía crear “funciones” en cuyo interior podíamos escribir código Razor (mezclando marcado y C#) que podía ser invocado desde distintos puntos:
Pero bueno, ciertamente existe una forma que, aunque no con la misma limpieza, al menos nos permite acercarnos un poco a nuestra añorada directiva ;)
El truco consiste en crear un delegado en forma de función lambda
Publicado en Variable not found.
@helper
para crear porciones de HTML reutilizables en el interior de nuestras vistas, tanto para conseguir un código más limpio como para abrazar el principio DRY (Don’t Repeat Yourself), tan frecuentemente apaleado en la capa de presentación.Recordaréis que esta directiva permitía crear “funciones” en cuyo interior podíamos escribir código Razor (mezclando marcado y C#) que podía ser invocado desde distintos puntos:
@* File: Test.cshtml *|
@Multiplication(2)
@Multiplication(3)
@helper Multiplication(int x)
{
<h2>Multiplication table of @x</h2>
<ul>
@for (var i = 1; i <= 10; i++)
{
<li>@x * @i = @(x * i)</li>
}
</ul>
}
Además de definirlos y consumirlos desde la misma vista, también era posible crear helpers globales introduciéndolos en App_Code
, aunque esta opción me gustaba menos y creo que no la utilicé jamás en aplicaciones reales.
Pues bien, por algunas extrañas razones, en ASP.NET Core la directiva @helper
no está disponible, lo que puede complicarnos un poco a la hora de portar vistas antiguas o, simplemente, cuando queramos usarla para mejorar la legibilidad de nuestro código.
¿Podemos conseguir algo similar en ASP.NET Core?
En realidad, en ASP.NET Core existen muchas fórmulas para reutilizar código de marcado; es relativamente sencillo crear HTML helpers, view components, tag helpers o vistas parciales, que nos permitirían conseguirlo. Sin embargo, en mi opinión, ninguna de estas opciones ofrece una solución en determinados escenarios tan elegante, eficiente y fácil de escribir como@helper
.Pero bueno, ciertamente existe una forma que, aunque no con la misma limpieza, al menos nos permite acercarnos un poco a nuestra añorada directiva ;)
El truco consiste en crear un delegado en forma de función lambda
Func<T, IHtmlContent>
, cuyo cuerpo podemos expresar utilizando sintaxis Razor, como en el siguiente ejemplo:@* File: Test.cshtml *|
@{
Func<int, IHtmlContent> Multiplication = @<text>
<h2>Multiplication table of @item</h2>
<ul>
@for (var i = 1; i <= 10; i++)
{
<li>@item * @i = @( item * i)</li>
}
</ul>
</text>;
}
@Multiplication(2)
@Multiplication(3)
Pero ojo, que aunque a priori pueda parecer bastante similar a @helper
, encontraremos varios inconvenientes:- Primero, que al tratarse de una definición inline, sólo puede ser utilizada después de haber sido definida. En la práctica, quiere decir que debemos implementar estas funciones muy al principio de la vista para que estén disponibles en ella.
- Su definición y uso es estrictamente local al archivo actual, es decir, no podemos crearla en
_ViewImports.cshtml
o en_ViewStart.cshtml
y esperar que esté disponible en todas las vistas.
- Siempre necesitaremos especificar un tipo para
@item
en el primer parámetro genérico, incluso cuando no sea necesario. O sea, estas lambdas son obligatoriamente de la formaFunc<T, IHtmlContent>
, siendoT
el tipo deitem
. Si el código de marcado no usa@item
, podemos especificarlo comoobject
odynamic
y luego pasar un nulo al invocarlo:
Func<object, IHtmlContent> Time = @<h1>@DateTime.Now</h1>; ... @Time(null)
@helper
. Afortunadamente, en muchos issues de Github podemos encontrar referencias y comentarios relativos a la intención inicial del equipo de ASP.NET Core de traerlo de vuelta, aunque ciertamente no existen fechas ni señales del avance en este sentido :(Publicado en Variable not found.
Aún no hay comentarios, ¡sé el primero!
Enviar un nuevo comentario