Vecchia domanda, ma poiché la domanda chiede "utilizzando jQuery", ho pensato di fornire un'opzione che ti consente di farlo senza introdurre alcuna dipendenza dal fornitore.
Sebbene ci siano molti motori di modellazione là fuori, molte delle loro caratteristiche sono cadute in disgrazia di recente, con iterazione ( <% for
), condizionali ( <% if
) e trasformazioni ( <%= myString | uppercase %>
) viste come microlinguaggio nella migliore delle ipotesi e anti-pattern nel peggiore dei casi. Le moderne pratiche di templating incoraggiano semplicemente la mappatura di un oggetto sulla sua rappresentazione DOM (o altra), ad esempio ciò che vediamo con proprietà mappate sui componenti in ReactJS (specialmente componenti stateless).
Modelli in HTML
Una proprietà su cui puoi fare affidamento per mantenere l'HTML per il tuo modello accanto al resto del tuo HTML, è l'utilizzo di un non-eseguibile <script>
type
, ad es <script type="text/template">
. Per il tuo 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 caricamento del documento, leggi il tuo modello e tokenizzalo usando un semplice file String#split
var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);
Nota che con il nostro token, lo ottieni nel [text, property, text, property]
formato alternativo . Questo ci permette di mapparlo bene usando un Array#map
, con una funzione di mappatura:
function render(props) {
return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}
Dove props
potrebbe assomigliare { url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }
.
Mettendo tutto insieme supponendo che tu abbia analizzato e caricato itemTpl
come sopra, e hai un items
array nell'ambito:
$('.search').keyup(function () {
$('.list-items').append(items.map(function (item) {
return itemTpl.map(render(item)).join('');
}));
});
Questo approccio è anche solo appena jQuery: dovresti essere in grado di adottare lo stesso approccio usando javascript vanilla con document.querySelector
e .innerHTML
.
jsfiddle
Modelli all'interno di JS
Una domanda da porsi è: vuoi veramente / hai bisogno di definire i modelli come file HTML? Puoi sempre componentizzare + riutilizzare un modello nello stesso modo in cui riutilizzeresti la maggior parte delle cose che vuoi ripetere: con una funzione.
In es7-land, usando la destrutturazione, le stringhe di template e le funzioni freccia, puoi scrivere delle funzioni componenti decisamente carine che possono essere facilmente caricate usando il $.fn.html
metodo sopra.
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>
`;
Quindi potresti facilmente renderlo, anche mappato da un array, in questo modo:
$('.list-items').html([
{ url: '/foo', img: 'foo.png', title: 'Foo item' },
{ url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));
Oh e nota finale: non dimenticare di disinfettare le tue proprietà passate a un modello, se vengono lette da un DB, o qualcuno potrebbe passare in HTML (e quindi eseguire script, ecc.) Dalla tua pagina.