古い質問ですが、「jQueryを使用する」という質問なので、ベンダーに依存せずにこれを実行できるオプションを提供したいと思いました。
多くのテンプレートエンジンが世の中にありますが、それらの機能の多くは最近好評を博しており<% for
、イテレーション()、条件文(<% if
)、変換(<%= myString | uppercase %>
)は、せいぜいマイクロ言語と見なされ、最悪の場合はアンチパターンと見なされています。最新のテンプレートプラクティスでは、オブジェクトをDOM(または他の)表現に単純にマッピングすることを奨励しています。
HTML内のテンプレート
あなたがHTMLの残りの部分の横にテンプレートのHTMLを維持するために頼ることができます1つの特性は、非実行用いることで<script>
type
、例えば<script type="text/template">
。あなたの場合:
<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>
ドキュメントの読み込み時に、テンプレートを読み取り、単純な String#split
var itemTpl = $('script[data-template="listitem"]').text().split(/\$\{(.+?)\}/g);
トークンを使用すると、代替[text, property, text, property]
形式で取得できることに注意してください。これによりArray#map
、マッピング関数とともに、を使用してうまくマッピングできます。
function render(props) {
return function(tok, i) { return (i % 2) ? props[tok] : tok; };
}
どこにprops
見えるでしょう{ url: 'http://foo.com', img: '/images/bar.png', title: 'Lorem Ipsum' }
。
itemTpl
上記のように解析してロードし、items
範囲内に配列があると仮定して、すべてをまとめます。
$('.search').keyup(function () {
$('.list-items').append(items.map(function (item) {
return itemTpl.map(render(item)).join('');
}));
});
このアプローチも、かろうじてjQueryにすぎません- document.querySelector
およびでバニラJavaScriptを使用して同じアプローチをとることができるはず.innerHTML
です。
jsfiddle
JS内のテンプレート
自問する質問は次のとおりです。テンプレートをHTMLファイルとして定義することを本当に望んでいますか?テンプレートはいつでもコンポーネント化して、繰り返したいほとんどのことを再利用するのと同じ方法で、関数を使用してテンプレートを再利用できます。
es7-landでは、分解、テンプレート文字列、および矢印関数を使用して、$.fn.html
上記のメソッドを使用して簡単にロードできる実に見栄えのよいコンポーネント関数を記述できます。
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>
`;
その後、次のように、配列からマッピングされた場合でも、簡単にレンダリングできます。
$('.list-items').html([
{ url: '/foo', img: 'foo.png', title: 'Foo item' },
{ url: '/bar', img: 'bar.png', title: 'Bar item' },
].map(Item).join(''));
最後に、DBから読み取った場合や、誰かがページからHTMLを渡して(スクリプトを実行した場合など)、テンプレートに渡されたプロパティをサニタイズすることを忘れないでください。