Nota: Este post ha sido importado de mi blog de geeks.ms. Es posible que algo no se vea del todo "correctamente". En cualquier caso puedes acceder a la versión original aquí
Muy buenas!
En este post quiero comentaros una característica de Razor que yo considero que es una auténtica pasada: los templates.
Básicamente el meollo de todo está en la posibilidad de guardar el resultado de un parseo de Razor en un Func<T, HelperResult> siendo T el tipo del modelo que renderiza el template.
Veámoslo con código:
@{
Func<string, HelperResult> h =
@<h2>Esto es un template al que se le han pasado los datos: @item</h2>
;
}
<p>
Renderizamos el template: @h("datos")
</p>
<p>
Fijaos como nos guardamos en una Func<string, HelperResult> el resultado de renderizar un template razor (en este caso el template <h2>…</h2>). Fijaos en tres detalles:
</p>
<ol>
<li>
Dado que la variable h está declarada como Func<string, HelperResult> el tipo del modelo en este template es “string”
</li>
<li>
Para acceder al modelo que se pasa al template se usa @item
</li>
<li>
Al final del template Razor ponemos un ; (eso es una declaración C# y como tal <em>debe</em> terminar en punto y coma).
</li>
</ol>
<p>
Luego más adelante renderizamos el template, con el código: @h("datos")
</p>
<h2>
<strong>Eh!! Eso no es lo mismo que @helper?</strong>
</h2>
<p>
Si conoces @helper te puede parecer que esto no es muy novedoso. Con @helper podemos crear helpers inline de la siguiente manera:
</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">@helper h2(string s) {<span style="color: #0000ff"><</span><span style="color: #800000">h2</span><span style="color: #0000ff">></span>Esto es un helper: @s<span style="color: #0000ff"></</span><span style="color: #800000">h2</span><span style="color: #0000ff">></span>}</pre>
<p>
</div>
<p>
Y lo podíamos invocar con:
</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">@h2("ufo")</pre>
<p>
</div>
<p>
Por lo que parece que viene a ser lo mismo. Y es que, en el fondo, ambas construcciones devuelven un HelperResult.
</p>
<blockquote>
<p>
<strong>Nota: </strong>Si quieres más información sobre @helper, léete el post que hizo el maestro hace algún tiempecillo: <a title="http://www.variablenotfound.com/2010/11/y-mas-sobre-helpers-en-razor.html" href="http://www.variablenotfound.com/2010/11/y-mas-sobre-helpers-en-razor.html">http://www.variablenotfound.com/2010/11/y-mas-sobre-helpers-en-razor.html</a>
</p>
</blockquote>
<p>
Lo interesante no es que ambas construccione se parezcan, lo que quiero recalcar es que…
</p>
<p>
<strong>… Los templates son Func<T, HelperResult>!</strong>
</p>
<p>
Lo pongo así en negrita porque eso es importante, y a la vez me sirve de título. Si los templates Razor son Func<T, HelperResult>… <em>cualquier método que reciba un Fun<T, HelperResult> puede recibir un template Razor</em>…
</p>
<p>
… Incluídos los helpers!
</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">@helper Repeater(<span style="color: #0000ff">int</span> count,Func<dynamic, HelperResult> template, <span style="color: #0000ff">string</span> data) {<br /> <ul><br /> @<span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> idx=0; idx<count; idx++)<br /> {<br /> <li>@template(<span style="color: #0000ff">new</span> { Text = data, Index = idx })</li><br /> }<br /> </ul> <br />}<br /><br />@Repeater(10, @<span>@item.Text (item: #@item.Index)</span>, <span style="color: #006080">"Ufo"</span>)</pre>
<p>
</div>
<p>
En este código:
</p>
<ol>
<li>
Declaramos un helper, llamado Repeater que acepta tres parámetros:
</li>
<ol>
<li>
Un entero
</li>
<li>
Un Func<dynamic, HelperResult> que <em>por lo tanto podrá ser un template Razor</em>
</li>
<li>
Una cadena
</li>
</ol>
<li>
El helper se limita a crear una lista y luego:
</li>
<ol>
<li>
Crea tantos <li> como indica el paràmetro count y en cada id
</li>
<ol>
<li>
Evalúa el segundo parámetro <em>(que es el Func) y le pasa como parámetro un objeto anonimo con dos propiedades (Text e Index), donde Text es el tercer parámetro que recibe (y index el valor de la iteración actual</em>).
</li>
</ol>
</ol>
<li>
Cuando invocamos al helper, le pasamos como primer parámetro el número de repeticiones, como segundo parámetro <strong>un template de Razor</strong>. Fijaos que dentro de dicho template:
</li>
<ol>
<li>
Accedemos a las propiedades @item.Text y @item.Index. Eso podemos hacerlo porque hemos declarado el tipo del modelo de dicho template como <em>dynamic</em> y por eso nos compila (y nos funciona porque el helper cuando invoca el template crea esas propiedades en el objeto anónimo).
</li>
</ol>
</ol>
<p>
El código HTML generado por dicha llamada al helper Repeater es:
</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"><span style="color: #0000ff"><</span><span style="color: #800000">ul</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #0)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #1)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #2)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #3)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #4)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #5)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #6)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #7)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #8)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /> <span style="color: #0000ff"><</span><span style="color: #800000">li</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">span</span><span style="color: #0000ff">></span>Ufo (item: #9)<span style="color: #0000ff"></</span><span style="color: #800000">span</span><span style="color: #0000ff">></</span><span style="color: #800000">li</span><span style="color: #0000ff">></span><br /><span style="color: #0000ff"></</span><span style="color: #800000">ul</span><span style="color: #0000ff">></span> </pre>
<p>
</div>
<p>
Espero que el post os haya resultado interesante!!! 😉
</p>
<p>
Saludos!
</p>