jQueryテンプレートの使用

はじめに



jQuery Templatesプラグインは、クライアント側でjQuery拡張機能として機能する「テンプレートエンジン」です。



このプラグインは、ブラウザでJavaScriptオブジェクトと配列にあるデータを表示するのに役立ち、HTMLコードの作成、特殊文字のエスケープなどの日常的な操作からあなたを救います。 さらに、非常に興味深い機能があります。たとえば、ソースデータを変更するときに、ヘルプを使用して作成されたHTMLコードを更新できます。



もちろん、 jQueryテンプレートは唯一の「テンプレートエンジン」ではありませんが、 jQueryチームからのサポートという代替オプションよりも大きな利点があります。 これにより、このプラグインが放棄されることを恐れず、新しいバージョンのブラウザがリリースされたときに発生するさまざまな問題を独自に解決する必要があります。



この記事では、 jQueryテンプレートの主な機能について説明し、さまざまなシナリオでその動作を実証します。その後の記事では、メインのプラグインコード( jQuery Templates Plus )に含まれない機能とテンプレート言語の拡張について説明します。





ちょっとした歴史



このプラグインは、MicrosoftでJavaScript Micro-templatingライブラリ (著者-John Resig )に基づいて開発されました。開発に関する詳細は、 Stephen Waltherのブログ記事「 jQueryテンプレートの紹介 」およびJohn Resigの投稿「 Templating Syntax 」で確認できますjQueryフォーラム。 昨年10月以来、 jQueryテンプレートjQuery DataLink 、およびjQueryグローバリゼーションプラグインはjQueryプロジェクトの一部となっています



パート1、理論



仕事を始める



始めましょう。 次の例は、配列で指定された映画のリストを示しています(この例の完全なコードはBasicSample1.htmファイルにあります)。



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>  (1)</title> <link href="Styles/Default.css" rel="Stylesheet" type="text/css" /> <script src="Scripts/jquery-1.5rc1.js" type="text/javascript"></script> <script src="Scripts/jquery.tmpl.js" type="text/javascript"></script> <script src="DataItems.js" type="text/javascript"></script> <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> <h2> ${title} </h2> <p> : ${director}<br />  : ${actors}<br /> : ${year} </p> </div> </div> </script> <script type="text/javascript"> $(function () { $('#movieTmpl').tmpl(dataItems).appendTo('#movieListBag'); }); </script> </head> <body> <h1>  (1)</h1> <div id="movieListBag"> </div> </body> </html>
      
      





そして、ブラウザに表示されるものは次のとおりです。











この例を詳しく見てみましょう。



したがって、私が最初に行うことは、 jQuery Core LibraryjQuery Templatesを接続することです。



 <script src="Scripts/jquery-1.5rc1.js" type="text/javascript"></script> <script src="Scripts/jquery.tmpl.js" type="text/javascript"></script>
      
      





以前、 jQueryテンプレートjQueryコアライブラリに含まれると繰り返し言われていましたが、1月24日にリリースされたjQuery 1.5 RC1では、テンプレートがまだありません。



次に、ムービーリストをロードします。



 <script src="DataItems.js" type="text/javascript"></script>
      
      





もちろん、あなたにとって便利な方法でソースデータを準備することができます-AJAXリクエストを使用して取得する、ユーザー入力に基づいて作成するなど、静的スクリプトは例としてのみ使用します。



DataItems.jsファイルの内部は次のとおりです。



 var dataItems = [ { title: '', thumbnail: 'Bandits.jpg', director: ' ', actors: [' ', '  ', ' '], year: 2001, budget: 95000000, grossRevenue: 67631903, rating: 0, frames: ['Bandits-1.jpg', 'Bandits-2.jpg', 'Bandits-3.jpg', 'Bandits-4.jpg', 'Bandits-5.jpg'] }, ...
      
      





次のステップは、テンプレートを作成することです:



 <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> <h2> ${title} </h2> <p> : ${director}<br />  : ${actors}<br /> : ${year} </p> </div> </div> </script>
      
      





テンプレートはSCRIPTタグに配置され、MIMEタイプとしてtext / x-jquery-tmplを指定していることに注意してください。 文書の解析中に不明なMIMEタイプに遭遇した場合、ブラウザーはSCRIPTタグの内容を解釈しようとしません。これは必要なことです。



一般的に、テンプレートは、たとえばDIVタグなどの任意のタグに配置できます。



 <div id="movieTmpl" style="display: none"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> <h2> ${title} </h2> <p> : ${director}<br />  : ${actors}<br /> : ${year} </p> </div> </div> </div>
      
      





ただし、この場合、副作用は回避できません。 ブラウザは間違いなくテンプレートコードを解釈しようとします。



たとえば、上記の例では、存在しない画像をアップロードしようとします。











しかし、テーブルを使用した場合はさらに興味深い場合があります(この例ではTEHEKに感謝します!)



 <div id="movieTmpl" style="display: none"> <table> <tbody> {{each dataItems}} <tr> <td>${title}</td> <td>${director}</td> <td>${year}</td> </tr> {{/each}} </tbody> </table> </div>
      
      





Internet ExplorerとOperaはこのコードを正しく処理します:











しかし、ChromeとFire Foxはテーブルの外側に余分なコードを「プッシュ」し、その結果、テーブルは空になります...ハッピーデバッグ! ;-)











SELECTタグの場合、同様のパターンが観察されます。



開発するとき、IntelliSenceのすべての利点を活用するためにDIVタグにテンプレートを配置し、それらをSCRIPTタグに移動することをお勧めします。



そして最後に、次の呼び出しでテンプレートをインスタンス化します。



 $('#movieTmpl').tmpl(dataItems).appendTo('#movieListBag');
      
      





この場合に何が起こるか、以下の図に示しました。











だから:

  1. .tmpl()メソッドは、テンプレートのテキストを取得します-つまり $( '#movieTmpl')を呼び出して取得し要素の内部テキスト
  2. テンプレートのテキストがコンパイルされ、それに基づいてJavaScript関数が作成されます。
  3. 「テンプレートインスタンス」が作成されます。これは、 .tmpl()メソッドへの引数として渡されるデータ要素( データフィールド)へのリンクを含むオブジェクトです。 配列、オブジェクト、 nullを .tmpl()メソッド渡すか、引数なしで呼び出すことができます。 配列を渡すと、配列の各要素に対して、この要素を参照するテンプレートの独自のインスタンスが作成されます。他のすべての場合は、1つのインスタンスのみが作成されます。
  4. コンパイルされたテンプレート関数が呼び出され、インスタンスオブジェクトが渡されます。 この関数は、すべての置換が行われたテンプレートのテキストを返します。
  5. 前の手順で取得したテキストは、HTML要素のコレクションに変換されます。 これらの要素へのリンクは、インスタンスオブジェクト( ノードフィールド)にも格納されます。これにより、ソースデータが変更されたときにテンプレートの「出力」を簡単に更新できます(「動的更新」セクションを参照)。
  6. 最後に、 .tmpl()メソッドは、 appendTo( '#movieListBag')を呼び出してドキュメントに追加されるHTML要素のjQueryコレクションを返します。




表現



$ {...}タグは、テンプレートに値を代入するために使用されます。 このタグ内で、 .tmpl()メソッドに渡されるオブジェクトのプロパティの名前と、関数呼び出しを含む有効なJavaScript式の両方を指定できます。



オブジェクト(配列要素)のプロパティを使用する:



 <h2> ${title} </h2>
      
      





JavaScript式の使用:



 <p> : $${(budget / 1000000).toFixed(0)} .<br /> : $${(grossRevenue / 1000000).toFixed(1)} . </p>
      
      







テンプレートインスタンスのフィールドとメソッド



式の中では、 $ item変数を介してテンプレートの現在のインスタンスにアクセスでき、現在のdata itemにアクセスするには、 $ data変数を使用します。



各テンプレートインスタンスには、次のフィールドが含まれます。

  1. データ -テンプレートインスタンスに関連付けられたデータ要素へのリンクが含まれています。
  2. tmpl-レンダリングに使用されるコンパイル済みテンプレートへのリンクが含まれています。
  3. parent - {{tmpl}}タグを使用して別のテンプレートからテンプレートが呼び出された場合、テンプレートの「親」インスタンスへのリンクが含まれます。
  4. ノード -レンダリング後、テンプレートを適用した結果として生成されたHTML要素へのリンクが含まれます。


さらに、 .tmpl()メソッドは、 dataoptionsの 2つの引数を受け入れます 。 あなたはすでにデータ引数に会っています 、データ要素へのリンクはそれを通して渡されます。 また、 options引数を使用して、オブジェクトへの参照を渡すことができます。そのオブジェクトのすべてのフィールドとメソッドは、 .tmpl()メソッドで作成された各テンプレートインスタンスに転送されます。



以下は、このパラメーターの使用例です。



 <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> <h2> ${title} </h2> <p> : ${director}<br />  : ${actors}<br /> : ${year}<br /> : $${$item.formatBudget(budget)} .<br /> : $${$item.formatGrossRevenue(grossRevenue)} . </p> </div> </div> </script>
      
      





 $(function () { $('#movieTmpl') .tmpl( dataItems, { formatBudget: function (value) { return (value / 1000000).toFixed(0); }, formatGrossRevenue: function (value) { return (value / 1000000).toFixed(1); } }) .appendTo('#movieListBag'); });
      
      





この例では、関数呼び出しを使用して予算値と料金をフォーマットしますが、グローバルネームスペースを「乱雑」にしないために、 optionsパラメーターを介してそれらを渡し、その後これらの関数は現在のテンプレートインスタンスのメソッドとして使用可能になりました。



最後に、テンプレートインスタンスにはupdate()およびhtml()メソッドが含まれています。これらの使用方法については後で説明します。



コンパイルされたテンプレートはどのように見えますか?



テンプレートをコンパイルする.template()メソッドを使用すると、コンパイルされたテンプレートがどのように見えるかを確認できます。 このメソッドは、内容が見やすい関数オブジェクトを返します。



 $('#compiledTemplateBag').text('' + $('#movieTmpl').template());
      
      





コンパイル後に上記の例で使用されるテンプレートは次のとおりです(テキストは読みやすくするためにフォーマットされています)。



 function anonymous(jQuery, $item) { var $ = jQuery, call, _ = [], $data = $item.data; with ($data) { _.push('<div class="movie-bag"> <img src="Content/Thumbnails/'); if (typeof (thumbnail) !== 'undefined' && (thumbnail) != null) { _.push($.encode((typeof (thumbnail) === 'function' ? (thumbnail).call($item) : (thumbnail)))); } _.push('" class="thumbnail" /> <div class="base-info"> <h2> '); if (typeof (title) !== 'undefined' && (title) != null) { _.push($.encode((typeof (title) === 'function' ? (title).call($item) : (title)))); } _.push(' </h2> <p> : '); if (typeof (director) !== 'undefined' && (director) != null) { _.push($.encode((typeof (director) === 'function' ? (director).call($item) : (director)))); } _.push('<br />  : '); if (typeof (actors) !== 'undefined' && (actors) != null) { _.push($.encode((typeof (actors) === 'function' ? (actors).call($item) : (actors)))); } _.push('<br /> : '); if (typeof (year) !== 'undefined' && (year) != null) { _.push($.encode((typeof (year) === 'function' ? (year).call($item) : (year)))); } _.push(' </p> </div> </div>'); } return _; }
      
      





これで、 $ {...}タグで指定された式がどのように処理されるかを理解する必要があると思います。この理解は、デバッグ時に非常に役立ちます。 実際、 jQueryテンプレートはテンプレートテキストの比較的単純な変換を実行するため、式に誤りがあると、エラーメッセージは変換関数の結果として受信したテキストを参照し、非常にわかりにくい場合があります。











残念ながら、テンプレートがエラーでコンパイルされた場合、特別なトリックなしではエラーのある関数テキストを見ることができません。 対応するメソッドはprivateとして宣言されます。



おそらく、これはjQueryテンプレートの作業についてのストーリーであり、完成して実用的なアプリケーションに移行する価値があります。



パート2、実用的



条件



特定の条件に応じてテンプレートの一部を適用するために、タグ{{if}} ... {{else}} ... {{/ if}}jQueryテンプレートで使用されます。



次の例は、これらのタグの使用方法を示しています(例の完全なコードはIfElseTag.htmファイルにあります)。



 <p> : {{if $item.data.media == 'dvd'}} <img src="Images/media-dvd.png" /> {{else $item.data.media == 'blue-ray'}} <img src="Images/media-blueray.png" /> {{else}} <img src="Images/media-unspecified.png" /> {{/if}} </p>
      
      





ご想像のとおり、このコードは、映画が置かれているメディアアイコンを表示するように設計されています。 ブラウザでは次のように表示されます。











{{if}}および{{else}}タグで条件として有効なJavaScript式を使用できます。



収集処理



テンプレート内のコレクションを処理するには、タグ{{each}} ... {{/ each}}を使用します。 次の例は、 {{each}}タグを使用してアクターをリストする方法を示しています(この例の完全なコードはEachTag1.htmにあります )。



  : {{each actors}} ${$value} {{if $index < $data.actors.length - 1}} , {{/if}} {{/each}}
      
      





ブラウザでは、この例は次のとおりです。











配列、オブジェクト、またはjQueryコレクションを引数として{{each}}タグに渡すことができます。 内部的には、 {{each}}タグはjQuery.each()呼び出しを使用するため、 jQuery.each()の動作に関するドキュメントに記載されていることはすべて{{each}}タグに当てはまります。 以下の例は、 {{each}}タグを使用してオブジェクトのすべてのプロパティを表示する方法を示しています(完全なサンプルコードはEachTag2.htmファイルにあります)。



 <script id="objTmpl" type="text/x-jquery-tmpl"> <div> <dl> {{each $data}} <dt> ${$index} </dt> <dd> ${$value} </dd> {{/each}} </dl> </div> </script>
      
      





{{each}}タグ内では、現在の配列要素への参照を含む$ valueと、現在の配列要素またはプロパティ名のインデックスを含む$ indexの 2つの変数を使用できます。



もちろん、 {{each}}タグ内で他のタグを使用できます。さらに、 $ item変数と$ data変数は引き続き使用できます。 上記の例では、変数$ indexおよび$ dataとタグ{{if}}を使用して、俳優の名前の間にコンマを表示しています。残念ながら、変数$ lastは提供されていませんが、非常に便利です。



最後に、突然そのようなニーズがある場合は、デフォルトの変数名を変更できます。 以下の例では、これらの名前はmyIndexおよびmyValueに変更されています (完全なサンプルコードはEachTag3.htmファイルにあります)。



  : {{each(myIndex, myValue) actors}} ${myValue} {{if myIndex < $data.actors.length - 1}} , {{/if}} {{/each}}
      
      





ところで、 $インデックス変数の名前のみを変更しようとしても、何も良い結果にはなりません。エラーは発生しませんが、現在の値にもアクセスできません。



ネストされたテンプレート



テンプレートは非常に大きくなる可能性があります。そして、テンプレートを小さなボリュームのいくつかの部分に分割するか、論理的に別のテンプレートに分離する繰り返し部分を含めることは理にかなっています。 jQueryテンプレートでは、これは{{tmpl}}タグを使用して呼び出されるネストされたテンプレートを使用して行われます。



以下の例は、テンプレートコードの一部を別のテンプレートに抽出する方法を示しています(完全なサンプルコードはNestedTemplates1.htmファイルにあります)。



 <script id="movieTmpl" type="text/x-jquery-tmpl"> ... <p> : ${director}<br />  : {{tmpl '#actorsTmpl'}}<br /> : ${year} </p> ... </script> <script id="actorsTmpl" type="text/x-jquery-tmpl"> {{each actors}} ${$value} {{if $index < $data.actors.length - 1}} , {{/if}} {{/each}} </script>
      
      





{{tmpl}}タグには、呼び出されたテンプレートのjQueryセレクター、または以前にキャッシュに保存されたテンプレートの名前を含める必要があります。 なぜなら この例では、 {{tmpl}}タグには他の引数はありません。ネストされたテンプレートは親と同じデータ要素を受け取りますが、テンプレートの独自のインスタンスを持ち、その中のフィールドはテンプレートの親インスタンスを参照します。



次の例は、ネストされたテンプレートに新しいデータ項目を渡し、テンプレートの親インスタンスへのリンクを使用する方法を示しています。 .tmpl()メソッドを使用する場合と同様に、ネストされたテンプレートを呼び出すときに配列を指定すると、テンプレートは配列の各要素に適用されます(例の完全なコードはNestedTemplates2.htmファイルにあります)。



 <script id="movieTmpl" type="text/x-jquery-tmpl"> ... <p> : ${director}<br />  : {{tmpl(actors) '#actors_template'}}<br /> : ${year} </p> ... </script> <script id="actors_template" type="text/x-jquery-tmpl"> ${$data} {{if $data !== $item.parent.data.actors[$item.parent.data.actors.length - 1]}} , {{/if}} </script>
      
      





最後に、このセクションの最後の例は、ネストされたテンプレートにオプション引数を渡す方法を示し、同時に、 オプション引数を使用して処理済み配列の最後の要素を決定する方法を示します (例の完全なコードはNestedTemplates3.htmファイルにあります):



 <script id="movieTmpl" type="text/x-jquery-tmpl"> ... <p> : ${director}<br />  : {{tmpl(actors, { last: actors[actors.length - 1] }) '#actors_template'}}<br /> : ${year} </p> ... </script> <script id="actors_template" type="text/x-jquery-tmpl"> ${$data} {{if $data !== $item.last}} , {{/if}} </script>
      
      







変換



jQueryテンプレートのもう1つの興味深い機能は、 {{wrap}}タグを使用するHTMLマークアップの変換です(一般的に、ラップは「ラッピング」ですが、「変換」という用語は発生している本質をよりよく反映しているようです)。



{{wrap}}タグを使用する典型的な例はブックマークです:











内部は次のようになります(完全なサンプルコードは、 Transformation1.htmファイルにあります)。



 <script id="tabsContent" type="text/x-jquery-tmpl"> {{wrap(null, { viewState: $item.viewState }) '#tabsTmpl'}} <h1>English</h1> <div> <h2>The Ballad of East and West</h2> <h3>Rudyard Kipling</h3> <p>OH, East is East, and West is West...</p> </div> {{/wrap}} </script>
      
      





変換の初期データはtabContentテンプレートに配置されます-これは、引き続きインスタンス化するテンプレートです。



変換するHTMLマークアップは、 {{wrap}}タグに配置されます。 {{wrap}}タグの場合、 {[tmpl }}タグの場合とまったく同じ呼び出し表記が使用されます。つまり、セレクターまたはテンプレート名を指定し、オプションでデータ要素とオプションへのリンクを渡す必要があります。 この場合、 optionsパラメーターで、選択したブックマークのインデックスを含むviewStateオブジェクトへのリンクを渡します。



変換のコードは次のとおりです。



 <script id="tabsTmpl" type="text/x-jquery-tmpl"> <div class="tab-head"> {{each $item.html("h1", true)}} <div class="tab {{if $index == $item.viewState.index}}active{{/if}}"> ${$value} </div> {{/each}} </div> <div class="tab-body"> {{html $item.html("div")[$item.viewState.index]}} </div> </script>
      
      





ここで、 DIV.tab-headにはブックマークのショートカットが含まれ、 DIV.tab-bodyには選択したブックマークの内容が含まれています。



$ item.html( "h1"、true)}を呼び出すと、データがフェッチされます。 最初のパラメーター( filterは、最初のレベルの要素のフィルターを設定し、2番目のパラメーター( textOnly )は、選択した各要素の内部テキストのみを取得することを示します-つまり この場合、行のコレクションを取得します。各行には、対応するH1タグからのテキストが含まれます。 この文字列のコレクションから、ブックマークショートカットを作成します。



私はhtml()メソッドで任意のセレクターを指定できないことに少し動揺していますが、幸いなことに、このメソッドの結果にjQueryセレクターを使用する人はいません。



別の面白い点は、セレクターの設定方法に関連しています-お気に入りの単一引用符でセレクターを設定しようとすると、テンプレートのコンパイル時にエラーが発生します。



次のステップでは、アクティブなタブに対応するソースDIVから選択し、それをDIV.tab-bodyに入れます。 この場合、 $ {...}ではなく{{html}}タグを使用することに注意してください- $ {...}タグを使用すると、特殊文字がエスケープされますが、この場合は私にとって必要ありません。



最後に、テンプレートをインスタンス化します。



 var viewState = { index: 0 }; $('#tabsContent').tmpl(null, { viewState: viewState }).appendTo('#tabsBag');
      
      





ブックマークのクリックハンドラーを設定します。



 $('#tabsBag').delegate('.tab', 'click', function () { var item = $.tmplItem(this); item.viewState.index = $(this).index(); item.update(); });
      
      





クリックハンドラで何が起こりますか? まず、 $ .tmplItem(this)を呼び出すことにより、現在の要素に関連付けられているテンプレートインスタンスへのリンクを取得します。 次に、選択したブックマークのインデックスを変更します。テンプレートの各インスタンスにviewStateオブジェクトへの参照があることを覚えていますか? 最後に、テンプレートインスタンスのupdate()メソッドを呼び出します。これにより、テンプレートが再度レンダリングされますが、 viewStateの値が異なります。



次の例はより複雑ですが、より便利です。



前の例との最初の違いは、変換のソースデータを動的に作成することです(完全な例のコードはファイルTransformation2.htmにあります)。



 <script id="movieListTmpl" type="text/x-jquery-tmpl"> {{wrap(null, {viewState: $item.viewState}) '#tabsTmpl'}} {{tmpl(dataItems) '#movieTmpl'}} {{/wrap}} </script> <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> ... </div> </script>
      
      





 var viewState = { index: 0 }; $('#movieListTmpl').tmpl({ dataItems: dataItems }, { viewState: viewState }).appendTo('#tabsBag');
      
      





2番目の違いは ブックマーク名を持つタグは最初のレベルにありません。ショートカットを作成するとき、 jQueryセレクターを使用してこの情報を取得する必要があります。



 <script id="tabsTmpl" type="text/x-jquery-tmpl"> <div class="tab-head"> {{each $item.html("div")}} <div class="tab {{if $index == $item.viewState.index}}active{{/if}}"> ${$('h2', $value).text()} </div> {{/each}} </div> <div class="tab-body"> {{html $item.html("div")[$item.viewState.index]}} </div> </script>
      
      





ブラウザでは、この例は次のようになります。











テンプレートのキャッシュ



$( '#...')を呼び出すたびにTmpl(...)がテンプレートをコンパイルするため、最近のブラウザーではJavaScriptの速度が劇的に向上したにもかかわらず、パフォーマンスに非常に悪影響を及ぼす可能性があります。 JQueryテンプレートの開発者はこの明らかな事実を無視できなかったため、 jQueryテンプレートテンプレートをプリコンパイルおよびキャッシュするためのメカニズムを提供します。



テンプレートのコンパイルとキャッシュは次のとおりです。



 $('#movieTmpl').template('movieTmpl');
      
      





コンパイルされたテンプレートは、 movieTmplとしてjQueryテンプレートの内部キャッシュに保存されます 。 キャッシュされたテンプレートにアクセスするには、 jQuery.tmpl()メソッドが使用され、キャッシュされたテンプレートの名前が最初のパラメーターとしてテンプレートに渡されます。



 $.tmpl('movieTmpl', dataItems).appendTo('#movieListBag');
      
      





以下の例では、ムービーリストがナビゲートされ、キャッシュされたテンプレートがムービー情報の表示に使用されます。



テンプレートコードは、以前に使用したものと実質的に変わりません。唯一の違いは、ナビゲーションリンクが映画の説明の下に追加で配置されることです(この例の完全なコードはCachedTemplates.htmファイルにあります)。



 <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> <h2> ${title} </h2> <p> : ${director}<br />  : ${actors}<br /> : ${year} </p> </div> </div> <div> {{if $item.canMoveBack}} <a href="javascript:" class="nav-link" x-inc="-1">[]</a> {{/if}} {{if $item.canMoveFwd}} <a href="javascript:" class="nav-link" x-inc="1">[]</a> {{/if}} </div> </script>
      
      





コンパニオンスクリプトも簡単です。



 var movieIndex = 0; $(function () { $('#movieTmpl').template('movieTmpl'); updateMovie(); $('#movieBag').delegate('.nav-link', 'click', function () { movieIndex += parseInt($(this).attr('x-inc')); updateMovie(); }); }); function updateMovie() { $('#movieBag').empty(); $('#movieBag').append( $.tmpl('movieTmpl', dataItems[movieIndex], { canMoveBack: movieIndex > 0, canMoveFwd: movieIndex < dataItems.length - 1 })); }
      
      





ナビゲーションリンクをクリックするためのハンドラーは、選択したムービーのインデックスを変更し、 updateMovie()関数を呼び出します。この関数は、最初にムービーの説明でコンテナーをクリアし、次に新しいデータを入れます。



この例をブラウザで表示すると次のようになります。











動的なテンプレートの読み込み



残念ながら、以下に示すコードは機能しません。



 <script id="movieTmpl" src="Templates/DynamicLoading.htm" type="text/x-jquery-tmpl"></script>
      
      





もちろん、ブラウザは対応するファイルをダウンロードしますが、そのコンテンツにアクセスすることはできません。



ただし、テンプレートは別のファイルに配置することができ、これには文字通り1行の追加コードが必要です(完全なサンプルコードはDynamicLoading.htmファイルにあります)。



 $(function () { $.get('Templates/DynamicLoading.htm', {}, function (templateBody) { $.tmpl(templateBody, dataItems).appendTo('#movieListBag'); }); });
      
      





なぜならこの場合、テンプレートをテキスト形式で取得します。そのインスタンス化のために、jQuery.tmpl()メソッドが使用されます。これは、受信したテンプレートテキストが渡される最初の引数です。



はい、jQuery.tmpl()メソッドを使用して、キャッシュされたテンプレートを名前でインスタンス化し、テンプレートをテキスト(伝統!..)として指定します-ただし、それらを互いに区別するのに十分スマートです。



いくつかの関連テンプレートをダウンロードする必要がある場合は、WaitSyncライブラリを使用する(「非同期呼び出しの同期。WaitSync」を参照)、独自のシンクロナイザーを記述できます(完全なサンプルコードはDynamicLoading2.htmファイルにあります)。



 $(function () { var ws = new WaitSync(function () { $.tmpl('movieTmpl', dataItems).appendTo('#movieListBag'); }); $.ajax({ cache: false, url: 'Templates/MovieTmpl.htm', success: ws.wrap('MovieTmpl', function (templateBody) { $.template('movieTmpl', templateBody); }), error: ws.wrap('MovieTmpl', function () { alert('Error loading MovieTmpl.htm!'); }) }); $.ajax({ cache: false, url: 'Templates/ActorsTmpl.htm', success: ws.wrap('ActorsTmpl', function (templateBody) { $.template('actorsTmpl', templateBody); }), error: ws.wrap('ActorsTmpl', function () { alert('Error loading ActorsTmpl.htm!'); }) }); });
      
      





この場合、actorsTmplテンプレート名前呼び出されることに注意してください(ファイルTemplates \ MovieTmpl.htm):



 <p> : ${director}<br />  : {{tmpl(actors, { last: actors[actors.length - 1] }) 'actorsTmpl'}}<br /> : ${year} </p>
      
      







動的更新



実際のパートの最後のセクションでは、jQueryテンプレートのさらに2つのシナリオを示します。関連するデータの変更と関連するテンプレートの置換です。



以下の例では、映画ごとに、レーティングを変更する機能が追加されています(完全なサンプルコードはDynamicUpdate1.htmファイルにあります)。



 <script id="movieTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> <img src="Content/Thumbnails/${thumbnail}" class="thumbnail" /> <div class="base-info"> ... <p> : <img src="Images/rating-down.png" alt="" title="-1" class="rating-button" x-inc="-1" /> ${rating} <img src="Images/rating-up.png" alt="" title="+1" class="rating-button" x-inc="1" /> </p> </div> </div> </script>
      
      





関連コード:



 $(function () { $('#movieTmpl').tmpl(dataItems).appendTo('#movieListBag'); $('#movieListBag').delegate('.rating-button', 'click', function () { var item = $.tmplItem(this); item.data.rating += parseInt($(this).attr('x-inc')); item.update(); }); });
      
      





ご覧のとおり、このコードはトランスフォーメーションセクションのブックマークコードに非常に似ていますが、ブックマークを操作するときのみ共有viewStateオブジェクトにアクセスし、ここではテンプレートインスタンスに関連付けられたデータを操作します。



ブラウザでは、この例は次のようになります。











次の例は、関連するテンプレートの置換を示しています(完全なサンプルコードはファイルDynamicUpdate2.htmにあります)。



 <script id="movieShortTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> {{tmpl '#movieMainTmpl'}} <p style="clear: both"><a href="javascript:" class="more-details">[...]</a></p> </div> </script> <script id="movieFullTmpl" type="text/x-jquery-tmpl"> <div class="movie-bag"> {{tmpl '#movieMainTmpl'}} <p style="clear: both">  :</p> <div> {{each frames}} <img src="Content/Frames/${$value}" /> {{/each}} </div> <p><a href="javascript:" class="more-details">[...]</a></p> </div> </script>
      
      





ここでは、movieShortTmplmovieFullTmplの 2つのテンプレートを使用します。これらの共通部分は、movieMainTmplテンプレートで取り出されます。



関連コード:



 $(function () { var shortTemplate = $('#movieShortTmpl').template('shortTemplate'); var fullTemplate = $('#movieFullTmpl').template(); $.tmpl('shortTemplate', dataItems).appendTo('#movieListBag'); $('#movieListBag').delegate('.more-details', 'click', function () { var item = $.tmplItem(this); item.tmpl = item.tmpl === shortTemplate ? fullTemplate : shortTemplate; item.update(); }); });
      
      





このコードにはさらに説明が必要だと思います。



テンプレートを置き換えるには、コンパイルされたテンプレートへのリンクが必要です。これらのリンクは、.template()呼び出しを使用して取得します。また、shortTemplateテンプレート、ページのロード後にムービーのリストをレンダリングするために使用され、名前でインスタンス化できるようにキャッシュに保存します。



Over / Lessリンクをクリックするハンドラーのコードは、前の例のコードと非常に似ています。以前にコンパイルされたテンプレートの1 つへのリンクをtmplフィールドに割り当てupdate()メソッド呼び出してレンダリングします。



ブラウザでは、この例は次のとおりです。











おわりに



このリンクから記事で使用されているサンプルのコードをダウンロードできますjQueryテンプレートは、ASP.NET CDN Webサイトから



ダウンロードするか、GitHubリポジトリから直接ダウンロードできます。



ドキュメントjQueryのテンプレートで利用可能なウェブサイトのjQueryのドキュメント



例では、jQuery 1.5 RC1を使用しましたが、jQueryテンプレートはバージョンjQuery 1.4.2以降で機能します。前回のプロジェクトでは、このリンクが使用されました。



以下のリンクは、jQueryテンプレートの詳細を知るのに役立ちます



他の「テンプレートエンジン」と比較したjQueryテンプレートのパフォーマンスを体感するにはBrian Landau記事Benchmarking Javascript Templating Libraries」をご覧ください



結論として、この記事の作業中になされた貴重なコメントについて、Vitaly DilmukhametovDenis Gladkikhに感謝します。



All Articles