項目中有用到JST模板引擎,於是抽個時間出來,整理了下關於JST模板引擎的相關內容。
試想一個場景,當點擊頁面上列表的翻頁按鈕后,通過異步請求獲得下一頁的列表數據並在頁面上顯示出來。傳統的JS做法是編譯返回的數據后,依次遍歷列表對象,並組裝html代碼和數據,最終生成總字符串,然后塞到指定的列表容器里。當數據比較龐大時,這種處理方式非常低效率。更加高效且穩定的方法就是使用JST模板引擎來完成。
定義
JST模板引擎是一款基於JS的輕量級的跨瀏覽器框架,采用APL/GPL開放源代碼協議,可以輕松進行基於模板編程方式的JS引擎。它有以下特點。
1.采用標准的JS編寫,支持跨瀏覽器
2.模板語言類似於:freemarker等
3.用簡單的語法來描述字串以及操作DOM元素
4.方便的解析XML文件格式到指定模板
通過使用JST模板語言,可以大大減少服務器端的負擔,服務器端只管輸出數據就行,接下來的數據處理與顯示由JST來完成,這在使用AJAX技術的應用里非常高效。
使用步驟
引用相關的庫文件:template.js
當引用庫文件后,腳本會創建一個trimpath對象,這個對象包換以下幾種主要的方法。
1. TrimPath.parseDOMTemplate (elementId, optionalDocument),獲得模板對象。
這個方法是得到頁面中ID為elementId的DOM對象,獲得這個DOM的innerHTML,並將其解析為一個模板,這個方法返回一個templateObject對象,如果解析出錯,則拋出異常。
兩個參數:elementID為用作模板元素的ID,optionalDocument為可選參數。
一般將用作模板的DOM元素放在一個隱藏的textarea里,用textarea標簽來放置內容,是因為textarea的innerHTML能夠很好的保持數據結構,且不被瀏覽器解析。
2. TrimPath.parseTemplate (templateContentStr, optionalTemplateName)
解析模板方法,將一個字符串作為模板解析並返回一個templateObject。
兩個參數:templateContentStr 符合JST語法的字符串。optionalTemplateName 模板名稱,為可選參數。
TrimPath.parseTemplate() 和 TrimPath.parseDOMTemplate()的成功運行將產生一個 templateObject。 templateObject有一個主方法。templateObject.process ( contextObject, optionalFlags )
3. TemplateObject.process (contextObject, optionalFlags)
這個方法將模板和數據結合在一起,可以重復調用,如果沒有重新解析,templateObjects的緩存和重用將獲得最好的系統性能。這個函數的返回值是一個經過“渲染”過的模板的字符串。
兩個參數:參數contextObject 必須是一個對象,並將成為模板的一個訪問域。 它可以是JS中的任意對象,包含字符串, 數字, 日期, 對象和函數。
參數optionalFlags 可以是空值,也可以是一個下面列表描述的對象: throwExceptions 默認是false,當true的時候,process() 方法將重新拋出異常,當false的時候,任何異常將停止解析模板,並在方法返回值包含一個出錯信息。 keepWhitespace 默認是falsel,當值為true時,模板的空白將保留。當為false時,空白(換行、空格、TAB)將被截取。
4. String.prototype.process() 方法
String.prototype.process ( contextObject, optionalFlags )
做為一個便捷的方式為string對象加入一個process()的方法,讓它來執行解析模板的動作。參數跟process()一樣。
5. TrimPath.processDOMTemplate ( elementId, contextObject, optionalFlags, optionalDocument )
TrimPath.processDOMTemplate方法是調用TrimPath.parseDOMTemplate()和 then the process() 方法以獲得templateObject,並輸出templateObject.process()中返回的對象。
四個參數:elementID指模板內容的節點ID,contextObject, optionalFlags是templateObject.process()的參數,optionalDocument是TrimPath.parseDOMTemplate的參數。
JST的語法
1. 表達式
${expr}
${expr|modifier}
加%標識符是為了避免在表達式中出現“}”導致出錯的情況。
${%customer.firstName%}
2. 分支控制語句
JST語句就像是javascript語句一樣,也有if/else/for/function這些句子。
{if testExpr}
{elseif testExpr}
{else}
{/if}
3. for循環
item為單個元素,lists為數組,對象等。
{for item in lists}
{/for}
{list lists as item}
{/list }
4. 輔助函數defined,檢測一個變量是否已經定義。
{if defined('aa')}
aa is defineds: ${aa}
{/if}
案例說明
1. 引用相關的JS庫,template.js
2. 在隱藏的textarea里放上你想要顯示的html模塊內容,這塊內容就是要在頁面上渲染並展示的。
<#noparse> <textarea name="jst" id="jst-mdl-spcart"> <li data-pid="${pid}" data-index="${index}" data-type="${type}"{if type==1} data-cl="${colorType}" data-st="${scaleType}"{/if}> <div class="iteml"> <span class="checkbox u-icn{if checkStatus == 1} u-icn-1{/if}" onclick="mb.m.artspcart.sel(this)">選擇</span> </div> <div class="itemr"> <div class="info"> {if type == 1} <div class="pic{if colorType == 2} pic-1{/if}"> <a href="http://www.lofter.com/art/product-${pid}/" class="img {if scaleType==1}sz1{elseif scaleType==2}sz2{else}sz0{/if}" target="_blank"><img src="http://imgsize.ph.126.net/?imgurl=${showImg}_{if scaleType==1}100x100{elseif scaleType==2}75x112{else}145x96{/if}x1.jpg"></a> </div> {else} <div class="pic"> <span class="bor"></span> <span class="bor bor-1"></span> <span class="bor bor-2"></span> <a href="http://www.lofter.com/art/product-${pid}/" class="card" target="_blank"><img src="http://imgsize.ph.126.net/?imgurl=${showImg}_194x136x1.jpg"></a> </div> {/if} </div> </div> </li> </textarea> </#noparse>
noparse是為了防止這塊內容被解析掉,是ftl里的寫法。
3. 當發送完請求,執行回調函數並返回list之后,可以采用如下的方式來渲染模板並展示在頁面上。
function showTopTenInCity(cityData) {
var cityTopTenList={"cityTopTenList":cityData};
$("showCity").innerHTML = TrimPath.parseTemplate($("jst-mdl-spcart").value).process(cityTopTenList);
}
先使用TrimPath.parseTemplate()或TrimPath.parseDOMTemplate()生成一個模板對象,即templateObject,然后使用templateObject.process(data)解析該模板對象,生成模板和數據結合在一起的字符串。將要顯示的容器的innerHTML設為這個字符串的值。這種代碼展示渲染的過程比之前的字符串拼接更方便,更簡潔。