Pregunta antigua, pero como la pregunta es "usar jQuery", pensé en proporcionar una opción que le permita hacer esto sin introducir ninguna dependencia del proveedor.
Si bien hay muchos motores de plantillas, muchas de sus características han caído en desuso recientemente, con iteración ( <% for
), condicionales ( <% if
) y transformaciones (<%= myString | uppercase %>
) vistos como microlenguaje en el mejor de los casos y como antipatrones en el peor. Las prácticas modernas de creación de plantillas fomentan la simple asignación de un objeto a su representación DOM (u otra), por ejemplo, lo que vemos con las propiedades asignadas a los componentes en ReactJS (especialmente los componentes sin estado).
Plantillas dentro de HTML
Una propiedad en la que puede confiar para mantener el HTML de su plantilla junto al resto de su HTML es mediante el uso de un código no ejecutable <script>
type
, por ejemplo <script type="text/template">
. Para tu caso:
<script type="text/template" data-template="listitem">
<a href="${url}" class="list-group-item">
<table>
<tr>
<td><img src="${img}"></td>
<td><p class="list-group-item-text">${title}</p></td>
</tr>
</table>
</a>
</script>
Al cargar el documento, lea su plantilla y conviértala en token con un simple String#split
var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);
Tenga en cuenta que con nuestro token, lo obtiene en [text, property, text, property]
formato alterno . Esto nos permite mapearlo muy bien usando an Array#map
, con una función de mapeo:
function render(props) {
return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}
Dónde props
podría verse { url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }
.
Poniéndolo todo junto asumiendo que has analizado y cargado tu itemTpl
como arriba, y tienes una items
matriz dentro del alcance:
$('.search').keyup(function () {
$('.list-items').append(items.map(function (item) {
return itemTpl.map(render(item)).join('');
}));
});
Este enfoque también es apenas jQuery: debería poder adoptar el mismo enfoque usando javascript vanilla con document.querySelector
y .innerHTML
.
jsfiddle
Plantillas dentro de JS
Una pregunta que debe hacerse es: ¿realmente desea / necesita definir plantillas como archivos HTML? Siempre puede componenteizar + reutilizar una plantilla de la misma manera que reutilizaría la mayoría de las cosas que desea repetir: con una función.
En es7-land, usando desestructuración, cadenas de plantilla y funciones de flecha, puede escribir funciones de componentes de aspecto francamente bonito que se pueden cargar fácilmente usando el $.fn.html
método anterior.
const Item = ({ url, img, title }) => `
<a href="${url}" class="list-group-item">
<div class="image">
<img src="${img}" />
</div>
<p class="list-group-item-text">${title}</p>
</a>
`;
Entonces podría renderizarlo fácilmente, incluso mapeado desde una matriz, así:
$('.list-items').html([
{ url: '/foo', img: 'foo.png', title: 'Foo item' },
{ url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));
Ah, y nota final: no se olvide de desinfectar sus propiedades pasadas a una plantilla, si se leen desde una base de datos, o si alguien podría pasar HTML (y luego ejecutar scripts, etc.) desde su página.