Compartir a través de


Este artículo proviene de un motor de traducción automática.

Perspectivas sobre el cliente

El uso de JsRender con JavaScript y HTML

John Papa

Descargar el ejemplo de código

John PapaMuchas plataformas de desarrollo utilizan plantillas para reducir el código y simplificar el mantenimiento, y HTML5 y JavaScript no son una excepción.JsRender es una biblioteca de JavaScript que le permite definir una estructura reutilizable de una vez y volver a generar dinámicamente HTML.JsRender trae una nueva biblioteca de plantillas para el desarrollo de HTML5 que tiene una sintaxis de la etiqueta codeless y alto rendimiento, no tiene ninguna dependencia en jQuery ni sobre el modelo de objetos de documento (DOM), apoya la creación de funciones personalizadas y utiliza procesamiento puro basado en cadena.Esta columna describe escenarios para que JsRender es ideal y se muestra cómo utilizar sus distintas características.Todas las muestras de código pueden descargarse desde archive.msdn.microsoft.com/mag201204ClientInsight, y JsRender se puede descargar desde bit.ly/ywSoNu.

Segun Boris Moore y el blog del equipo de jQuery UI, en abril de 2011 el equipo decidido poner plantillas jQuery celebrar en favor de la creación de una biblioteca de representación lógica menos y basada en cadena.Esto llevó a Moore (uno de las fuerzas impulsoras detrás de plantillas jQuery) para crear JsRender y JsViews.Estas dos bibliotecas son efectivamente los reemplazos para las plantillas de jQuery.Puede leer más sobre la historia de plantillas y cómo ha evolucionado la JsRender en post de Moore sobre el jQuery plantillas y mapa de JsRender (bit.ly/AdKeDk) y del equipo de jQuery (bit.ly/fhnk8A).Cliente Insight explorará JsRender y JsViews en los próximos meses.

¿Por qué plantillas?

Usando plantillas con JavaScript reduce y simplifica el código.Sin plantillas, añadiendo una serie de elementos de la lista y otros elementos HTML para un conjunto de datos puede requerir manipulación DOM. del navegadorEsto es donde plantillas mediante un complemento como JsRender pueden ser muy útil para hacer el trabajo pesado.Por ejemplo, supongamos que usted recupera un conjunto de películas y desea mostrarlos.Podría escribir JavaScript y manipular el DOM, pero el código siguiente muestra que incluso esta tarea simple puede ser difícil de leer, incluso con la ayuda de jQuery:

// Without a template
var i = 1;
$(my.vm.movies).each(function () {
  var movie = this;
  $("#movieContainer1").append(
    "<div>" + i++ + ": " + movie.
name + " ("
    + movie.releaseYear + ")</div>");
});

El código está escrito totalmente con JavaScript y jQuery, pero puede ser difícil discernir el código HTML de los datos desde el código JavaScript. Utilizar una plantilla, más fácilmente podemos separar la estructura y eliminar la mayor parte del código JavaScript. La siguiente plantilla (01-with-and-without-templates-with-jquery.html en la descarga de código que lo acompaña) demuestra este concepto:

<script id="myMovieTemplate" type="text/x-jsrender ">
  <div>{{:#index+1}}: {{:name}} ({{:releaseYear}})</div>
</script>

Observe que la plantilla está envuelto en una etiqueta de script, su tipo se establece en consecuencia y ha dado un id por lo que pueden ser identificado más tarde. Rendering a template requires three aspects: a template, data and a container. La plantilla define cómo se procesará los datos y el contenedor define dónde hacerlo. El código siguiente muestra cómo representar una lista de películas utilizando la plantilla denominada myMovieTemplate para un elemento con el id de movieContainer:

$("#movieContainer").html($("#myMovieTemplate").render(my.vm.movies));

Este ejemplo utiliza jQuery para simplificar la sintaxis. Es importante señalar que el JsRender no es dependiente de jQuery. También se podría escribir el código para utilizar JsRender para procesar los datos utilizando la plantilla como se muestra aquí (02-jsrender-no-jquery.html en la descarga de código):

my.vm = {
  movies: my.getMovies()
};
jsviews.templates({
  movieTemplate: document.getElementById("myMovieTemplate").innerHTML
});
document.getElementById("movieContainerNojQuery").innerHTML
  = jsviews.render.movieTemplate(my.vm.movies);

Plantillas de representación

Puede representar plantillas utilizando JavaScript en varias formas. Primero te desea definir la plantilla como una cadena o en un <script> etiqueta. La <script> opción etiqueta es agradable cuando desea definir plantillas en el código HTML, darles un id y volver a utilizarlos. También puede crear plantillas de cuerdas, que le da la posibilidad de crear sobre la marcha en el código o incluso los Tire desde un almacén de datos.

El método de procesamiento se utiliza para representar el contenido HTML de datos utilizando una plantilla. Un conjunto de datos se puede procesar con una plantilla de declaró en <script> etiqueta utilizando la sintaxis $("# myTmpl").render(data). Por ejemplo, podría representar una lista de las películas con una plantilla mediante el siguiente código:

// #1: Render the my.vm data using the scriptTmpl from a script tag
var htmlString = $("#scriptTmpl").render(my.vm);
// Insert the htmlString into the DOM
$("#div1").html(htmlString);

También puede compilar una plantilla de una cadena mediante la función $.templates(tmplString) y establecer a una variable. Luego se puede procesar la plantilla compilada, como se muestra aquí:

// #2: Compile a template from a string, return a compiled template
var tmpl2 = $.templates(tmplString);
htmlString = tmpl2.render(my.vm);
$("#div2").html(htmlString);

También puede compilar una plantilla de una cadena utilizando la sintaxis de .templates (nombre, plantilla) $, como se muestra aquí:

// #3: Compile a template, name and register it
$.templates("myTmpl3", tmplString);
var htmlString = $.render.myTmpl3(my.vm);
$("#div3").html(htmlString);

En este ejemplo, la función de .templates $ compila una plantilla utilizando la cadena de tmplString y lo registra como una plantilla con nombre. La plantilla se puede acceder por su nombre y representan utilizando el .render $. Sintaxis de Name().

La función de .templates $ es similar a los métodos de jQuery como .css o .attrib en que proporciona una sintaxis alternativa para registrar y compilar varias plantillas en una sola llamada. En lugar de pasar dos parámetros (nombre y templateString), puede pasar un parámetro consistente en un objeto de asignación con pares de clave y valor de cada plantilla es estar registrado:

// #4: Compile multiple templates, register them and render
var tmplString2 = "<div>*** {{:movies.length}} Total Movies ***</div>";
$.templates({
  tmpl4a: tmplString,
  tmpl4b: tmplString2
});
htmlString = $.render.tmpl4a(my.vm);
htmlString += $.render.tmpl4b(my.vm);
$("#div4").html(htmlString);

Cada propiedad en el objeto se convierte en una plantilla con nombre y domicilio que puede procesarse. El valor de la propiedad es la cadena que se convertirá en la plantilla.

Tienes muchas opciones para crear, registrar y procesar las plantillas. Definir plantillas de etiquetas script es un enfoque común para la mayoría de los escenarios. Sin embargo, la creación de plantillas de cadenas ofrece mucha flexibilidad. La sintaxis ampliada anterior proporciona más flexibilidad para asociar otras funciones con plantillas con nombre (tales como declarar funciones auxiliares específicos de la plantilla). Todos estos ejemplos pueden encontrarse en 03-procesamiento-templates.html en la descarga de código.

Fundamentos de JsRender

JsRender plantillas constan de marcado HTML plus JsRender etiquetas, tales como el {{para...}} etiqueta o el {{:...}} etiqueta. Figure 1 shows the syntax for the most basic of JsRender tags: the {{: }} and {{> }} tags. Todas las etiquetas de plantilla de JsRender son envueltos con llaves dobles. The tag name (in this case the “:” or “>” character) can be followed by one or more parameters or expressions. (En el caso de la etiqueta {:}, el resultado de la expresión sería entonces procesarse.) Una vez que se ha definido una plantilla y hay datos para procesar en esa plantilla, puede procesarse.

Figura 1 Sintaxis básica de JsRender

Descripción Ejemplo Resultados
Valor de la propiedad firstName de elemento de datos con ninguna codificación {{: firstName}} Madelyn
Ruta de objeto simple propiedad anidados, con ninguna codificación {{: movie.releaseYear}} 1987
Comparación simple {{: movie.releaseYear < 2000}} verdadero
Valor con ninguna codificación {{: película. nombre}} Star Wars IV: Return of the Jedi
Valor codificado en HTML {{> película. nombre}} Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>
Valor codificado en HTML {{html:movie. nombre}} Star Wars: Episode VI: <span style='color:purple;font-style: italic;'>Return of the Jedi</span>

El código siguiente contiene un elemento HTML denominado película­contenedor (esto es donde se procesará la plantilla):

<div id="movieContainer" class="resultsPanel movieListItemMedium"></div>
<script id="movieTemplate" type="text/x-jsrender">
  <div class="caption">{{:name}}</div>
  <div class="caption">{{>name}}</div>
  <img src="{{:boxArt.smallUrl}}"/>
  <div class="text">Year Released: {{:releaseYear}}</div>
  <div class="text">Rating: {{:rating}}</div>
</script>

El código anterior también contiene la plantilla denominada película­plantilla, que define un div para mostrar el nombre de la película no utilizando ninguna codificación HTML utilizando la sintaxis {{: nombre}}. El título en los datos de ejemplo puede contener elementos HTML, por lo que para representar los elementos que contienen HTML es importante no utilizar codificación. Sin embargo, si desea procesar la codificación HTML, puede utilizar la sintaxis con el > caracteres o usar HTML (como se muestra en figura 1).

El valor de la propiedad de nombre contiene elementos HTML, por lo que para fines de demostración, el código anterior muestra el nombre del valor del propiedad con ninguna codificación ({{: nombre}}) y, a continuación, se muestra el valor codificado en HTML ({{> nombre}}). Puede ejecutar el ejemplo completo en 04-procesamiento-values.html en la descarga de código.

Los datos de la película muestra pasados a la plantilla tienen una propiedad para boxArt, que a su vez tiene una propiedad para la smallUrl de la imagen. La etiqueta de img src se establece por zambullirse en la jerarquía de la gráfica de un objeto mediante la boxArt.smallUrl de sintaxis de punto. Rutas de acceso también se puede recorrer utilizando corchetes, así que en lugar de escribir boxArt.smallUrl, el mismo resultado código lograrse mediante boxArt ['smallUrl'].

Es importante tener en cuenta que la sintaxis de JsRender también pueden utilizarse para representar otros valores, como los nombres de clases o ids de elementos HTML.

Representación de la plantilla de JsRender detecta si el parámetro de datos es una matriz o no. Si es una matriz, el valor devuelto es la concatenación de las cadenas que sería el resultado de cada uno de los elementos de la matriz individual pasando al método render. Por lo que la plantilla se procesará una vez para los datos de cada elemento y el resultado será la cadena concatenada.

El código siguiente muestra cómo se procesa un objeto de película único desde la matriz a la movieTemplate (la fuente completa está disponible en ejemplo 04-procesamiento-values.html):

my.vm = { movies: getMovies() };
$("#movieContainer").html($("#movieTemplate").render(my.vm.movies[1]));

La siguiente sección demostrará cómo podría escribirse la plantilla para recorrer una matriz.

Obtención de datos jerárquicos

Plantillas se utilizan a menudo para representar una serie de elementos, que a menudo pueden contener datos anidados y jerárquicos (gráficos de objetos). Figura2 muestra cómo JsRender puede iterar a través de una serie de datos utilizando el {{a}} de la etiqueta. El parámetro para el {{a}} etiqueta puede ser una matriz o una serie de arreglos de discos, que se itera.

Figura 2 iterando Basics

Descripción Ejemplo Resultados
Recorrer cada elemento de una matriz, utilizando "para"

{{para elenco}}

<div> {{: stageName}} </div>

{{/ para}}

Papa Landon

Ella Papa

Acceso al contexto de datos utilizando desde {{para teléfono}} <div> {{: desde}} </div> {{/ para}}

555-555-1212

555-555-1212

Los datos de la película de ejemplo define que cada película tiene una matriz de calificación de estrellas llamados RatingStars. La propiedad contiene la clase CSS para mostrar una estrella de calificación para la película. El código siguiente (de 05 para data.html en el código de ejemplo) muestra cómo recorrer en iteración todos los elementos de la matriz de RatingStars y representar el nombre de clase CSS utilizando el {{: desde}} sintaxis:

<ul>
  {{for ratingStars}}
  <li class="rating {{:#data}}"/>
  {{/for}}
</ul>

El token desde es una palabra clave de JsRender que representa el objeto que se itera. En este caso, la matriz de RatingStars contiene una matriz de cadenas, por lo que desde representará una cadena. La salida de este ejemplo se muestra en la figura 3, donde las estrellas de calificación se muestran junto a la imagen de la película.

Rendering an Object with and Without Encoding
Figura 3 representación de un objeto con y sin codificación

Arreglos de discos para plantillas

Cuando se pasa una matriz a una plantilla, la plantilla se procesa una vez para cada elemento de la matriz. Una plantilla procesa contra un elemento de datos único, pero si incorpora un {{}} etiqueta de plantilla con un parámetro de la matriz y, a continuación, la sección de la plantilla entre las etiquetas de apertura y cierre {{a}} y {{/ para}} va ser más itera. El código siguiente pasará un objeto my.vm que contiene una matriz de películas a la función de procesamiento para mostrar un elemento de la lista para cada película (el código fuente completo puede encontrarse en la muestra 06-Si-else.html):

$("#movieList").html($("#movieTemplateMedium").render(my.vm));

La plantilla se procesará como contenido de la <ul> elemento con el identificador movieList:

 

<ul id="movieList"></ul>

Figura 4 muestra la película de plantilla­TemplateMedium comienza por procesamiento <li>. Para cada película en la matriz, un <li> se procesará en el contenedor <ul>.

La plantilla de figura 4 recibe el objeto my.vm como su contexto y, a continuación, recorre la propiedad de matriz de películas debido a la {{para películas}} código. Si la plantilla recibió la my.vm.movies de matriz en lugar de my.vm, la {{a}} {{/ para}} bloque podría eliminarse, entonces se ejecutaría la plantilla para cada elemento de la matriz.

Figura 4 representar una lista de elementos y utilizando condicionales

{{for movies}}
  <li class="movieListItemMedium">
  <div class="caption">{{:name}}</div>
  {{if boxArt.smallUrl}}
    <img src="{{:boxArt.smallUrl}}"/>
  {{else}}
    <img src="../images/icon-nocover.png"/>
  {{/if}}
  <br/>
  <div class="text">Year Released: {{:releaseYear}}</div>
  <div class="text">rating: {{:rating}}</div>
  <ul>
    {{for ratingStars}}
      <li class="rating {{:#data}}"/>
      {{/for}}
  </ul>
  <br/>
  <div class="text">${{:salePrice}}</div>
  {{if fullPrice !== salePrice}}
    <div class="text highlightText">PRICED TO SELL!</div>
  {{/if}}
  </li>
{{/for}}

Recorrer caminos

Como hemos visto anteriormente, rutas pueden recorrer utilizando la sintaxis con punto o los corchetes. Sin embargo, también puede volver a una jerarquía de objetos utilizando #parent o identificar un elemento de la matriz utilizando corchetes. Por ejemplo, puede sustituir el código que muestra la etiqueta img en la plantilla con la siguiente:

<img src="{{:#parent.parent.data[2].boxArt.smallUrl}}"/>

El contexto de la plantilla es un elemento de la matriz de my.vm.movies. Así que por navegar hasta el padre dos veces, en el contexto se convertirá en el objeto my.vm. Entonces puede agarrar la película con índice 2 y utilizar la propiedad boxArt.smallUrl para la imagen. El resultado de esto sería mostrar la misma película (la tercera película) de cada película en la matriz (como se muestra en figura 5). No es exactamente ideal en esta situación, pero sirve de punto de mostrar cómo atravesar objetos arriba y abajo de la jerarquía.

Traversing Paths to Display the Same Movie Image for Every Movie
Figura 5 recorrer caminos para mostrar la misma imagen de película para cada película

Condicionales

La sintaxis de JsRender también admiten condicionales utilizando las etiquetas {{if}} y {{mas}} (se muestra en la figura 6). El {{si}} etiqueta puede estar seguido de cero, una o más etiquetas {{mas}} y, a continuación, un cierre {{/ si}} etiqueta. El contenido del bloque entre {{if}} etiqueta y el {{/ si}} (o hasta la primera etiqueta {{mas}} si existe alguno) se procesará en la salida sólo si el valor de la expresión en el {{if}} es "truthy".

Figura 6 condicionales, expresiones y operadores

Descripción Ejemplo Resultados
Crear un caso evaluado en una comparación de bloque

{{Si fullPrice! == salePrice}}

< div class = "texto highlightText" >

El precio a vender! </div>

{{/ Si}}

EL PRECIO DE VENTA!
Un bloque if/else

{{Si qtyInStock > = 10}}

En Stock

{{qtyInStock else}}

Sólo {{: qtyInStock}} izquierdo!

{{mas}}

No disponible.

{{/ Si}}

Sólo 5 izquierda!

La etiqueta {{mas}} puede actuar como un ifelse cuando incluye una expresión propia. Observe el segundo ejemplo en figura 6, que muestra un condicional con dos etiquetas otra cosa. Este código evalúa tres condiciones en secuencia.

El bloque después de una etiqueta {{someCondition else}} será salida si la condición se evalúa como true (o, más precisamente, truthy). Esta sintaxis puede utilizarse eficazmente como una instrucción switch/case para evaluar n número de condiciones.

Las expresiones utilizadas en las etiquetas de JsRender pueden ser expresiones complejas mediante evaluación operadores incluidos trazados, cadenas, números, funcionen llamadas y operadores de comparación como ===,! == y < =. Este es el caso tanto para las expresiones evaluaron y prestados por la etiqueta {:} y, aquí, para las expresiones condicionales en {{if}} y {{mas}} las etiquetas.

Uso de contadores y complejas expresiones condicionales

A veces es necesario mostrar o utilizar una variable de contador en una plantilla. Un tal escenario es cuando desea mostrar un número de fila en la plantilla. Otro tal escenario podría ser que desea asignar un id exclusivo a cada elemento en una plantilla, por lo que puede hacer referencia posteriormente. Por ejemplo, iterar a través de una lista de películas y envolverlos todo dentro de un <div> etiqueta. Puede asignar el id de la etiqueta div para ser movieDiv1, movieDiv2 y así sucesivamente. Entonces podría encontrar el elemento mediante su identificador cuando sea necesario, tal vez para enlazar a un controlador de eventos mediante la función de delegado de jQuery. Para ambos de estas situaciones, puede utilizar el númeroDeÍndice de JsRender palabra clave (que empieza en 0). Como se muestra en figura 7, númeroDeÍndice puede mostrarse en una plantilla muy fácilmente.

Figura 7 contadores y condicionales en múltiples expresiones

Descripción Ejemplo Resultados
Utilizando un índice para contar dentro de una plantilla

{{para películas}}

< div class = "caption" >

    {{:#index}}: {{:name}}

</div>

{{/ para}}

3: The Princess Bride
Utilizando operadores lógicos

{{Si stars.length || cast.length}}

< div class = "text" > elenco completo: </div>

{{/ Si}}

Reparto completo:

Con frecuencia una sola expresión no puede ser adecuada. JsRender soporta múltiples expresiones utilizando los operadores lógicos como || y & & ("o" y "y" respectivamente). Esto facilita combinar múltiples expresiones cuando desea evaluar alguno de ellos para ser verdad.

Recorrer juntos en múltiples arreglos de discos

El {{a}} etiqueta también puede iterar a través de múltiples arreglos de discos a la vez. Esto es útil cuando hay dos matrices que deban ser atravesado juntos. Por ejemplo, el código siguiente muestra cómo el de etiqueta será recorrer en iteración las estrellas y los arreglos de reparto juntos:

{{for stars cast}}
  <div class="text">{{:name}}</div>
{{/for}}

Si hay dos elementos de la matriz de estrellas y tres en la matriz de colada, se procesará contenido de cinco elementos de todos.

Se trata de una buena situación para usar la clave desde, demasiado, si los elementos de las matrices no son objetos (Propiedades) pero los valores de cadena simple. Por ejemplo, los arreglos de discos podrían ser matrices de cadenas de MobilePhones y HomePhones, y puede que desee mostrar en una sola lista.

Plantillas anidadas

Las aplicaciones suelen recuperan gráficos de objetos donde los objetos tienen propiedades cuyos valores son matrices de objetos que también pueden contener otras matrices de objetos. Estos escenarios rápidamente pueden resultar difíciles administrar al anidar múltiples {{a}} declaraciones. Considere que un objeto de cliente puede tener órdenes, que tienen elementos de orden, que tienen un producto que tiene almacenes. Este datos jerárquicos podrían procesarse utilizando múltiples {{a}} etiquetas. Esta es una gran situación donde el contenido de un {{a}} bloque puede ser empaquetado como una plantilla separada y procesa como una plantilla anidada. Esto puede reducir el código y hacerla más fácilmente legible y fácil de mantener y proporcionar para reutilización y modularidad de las plantillas.

Puede utilizar una plantilla anidada con un {{a}} etiqueta eliminando el contenido de bloque (haciéndola accionador) y especificar una plantilla externa mediante el parámetro tmpl. Por ejemplo, puede establecer el parámetro tmpl a ser el nombre de una plantilla con nombre (registrado mediante $.templates) o puede utilizar un selector de jQuery para una plantilla declarada en un bloque de script. La sintaxis siguiente utiliza la plantilla con nombre myTmpl para cada elemento de la matriz denominada myArray:

{{for myArray tmpl="myTmpl"/}}

El siguiente fragmento de código utilizará la plantilla con el id de movieTemplateMedium para cada elemento de la matriz de películas (a partir de la muestra 04-tmpl-combinado-iterators.html):

<ul>
  {{for movies
    tmpl="#movieTemplateMedium"/}}
</ul>

Puede iterar a través de múltiples arreglos de discos y aplicar una plantilla a ellos, así como. Por ejemplo, el siguiente fragmento de código utilizará el castTemplate para cada elemento de las estrellas y el elenco propiedades (que son ambas matrices de muestra 07-tmpl-combinado-iterators.html):

<ul>
  {{for stars cast tmpl="#castTemplate"/}}
</ul>

Observe que en cada uno de los anteriores fragmentos de código {{for}} tag es una etiqueta de cierre automático en lugar de una etiqueta de bloque con contenido. En lugar de iterar por su contenido de bloque, que es aplazar la iteración a la plantilla anidada indicada por la propiedad tmpl y es representar esa plantilla una vez para cada elemento de la matriz.

El {{si}} etiqueta de plantilla también puede utilizarse como una etiqueta de cierre automático que hace referencia a otra plantilla para su contenido, al igual que el {{a}} de la etiqueta. Por ejemplo, el código siguiente haría la plantilla con nombre myAddressTmpl si la dirección es truthy:

{{if address tmpl="myAddressTmpl"/}}

Las muestras disponibles para su descarga demuestran todas las características descritas en este artículo. Figura 8 muestra la lista de películas que se procesa con todas estas características de la muestra 07-tmpl -­archivo combinado iterators.html.

Putting It All Together
Figura 8 poniendo todos juntos

Más bajo las cubiertas

Esta columna muestra las características básicas de JsRender, pero hay mucho más en el interior. Por ejemplo, aunque las etiquetas condicionales pueden contener múltiples {{a}} etiquetas con condiciones (por ejemplo, una instrucción switch/case), puede haber formas más limpias para manejar esta situación, como la utilización de etiquetas personalizadas. JsRender admite etiquetas personalizadas para la compleja lógica, funciones auxiliares, desplazarse hasta el gráfico de objetos utilizando rutas, funciones de convertidor de clientes, permitiendo que el código JavaScript en las plantillas, encapsulación de plantillas y mucho más. Podrá explorar de algunas de estas técnicas en la próxima edición.

John Papa fue un evangelizador de Microsoft en los equipos de Silverlight Windows 8, donde animó el popular programa de televisión Silverlight. Ha presentado a nivel mundial en conferencias y sesiones para la construcción, mezcla, PDC, TechEd, Visual Studio Live! y eventos de DevConnections. Papa es también un Director Regional de Microsoft, un columnista forVisual Studio Magazine (perspectiva del Papa) y autor de videos de capacitación con Pluralsight. Puede seguirlo por Twitter en twitter.com/john_papa.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Boris Moore