在我的一篇關於智能搜索框異步加載數據的文章中,有博友給我留言,認為我手寫字符串拼接效率過低,容易出錯。在經過一段時間的摸索和學習之后,發現現在拼接字符串的方法都不在是自己去書寫了,而是使用Javascript引擎。而javascript引擎的實質就是幫我們把帶有JavaScript代碼的偽THTML語句編譯為HTML。
如果有不了解的朋友,可以前往這兩篇文章:
源碼地址:
回歸正題,以下對artTemplate模板引擎的介紹會分為如下幾部分內容:
1.artTemplate模板引擎的基本語法結構
2.artTemplate模板引擎的基本使用方法
2.1:使用一個type="text/html"
的script
標簽存放模板
2.2:在javascript中存放模板
2.3:嵌入子模板(include)
3.artTemplate模板引擎使用實戰
1.artTemplate基本語法結構
artTemplate的語法結構很簡單,就是{{}}。{{}}
符號包裹起來的語句則為模板的表達式。表達式又分為 輸出表達式,條件表達式,遍歷表達式,模板包含表達式。具體的可以看看GitHub:artTemplate 簡潔語法版。官網對語法介紹的還可以,不過在這里想在說一句,要記住表達式的寫法和表達式有哪些分類,對於理解引擎很有幫助。
2.artTemplate模板引擎的使用方法
首先,需要去官網下載 簡潔語法版 ,然后在body底部加載script文件。文件很小,只有2.7kb,可是功能十分強大。
2.1:使用一個type="text/html"
的script
標簽存放模板
使用script存放模板的時候要注意兩個方面。
一方面是必須給script標簽定義id,而且只能是id,不能是class。因為在使用template(id,data)方法的時候,該方法會根據id渲染模板,引擎內部會根據document.getElementById(id)
查找模板。如果使用class作為參數,artTemplate引擎會報錯。如果沒有 data 參數,將返回一渲染函數。
另外一方面是在<!DOCTYPE html>script標簽中的type類型默認為type/javascript。在script標簽中,必須重新聲明type類型為text/html,否則會沒有效果。
使用方法如下
<script id="test" type="text/html"> <h1>{{title}}</h1> <ul> {{each list as value i}} <li>索引{{i+1}} : {{value}}</li> {{/each}} </ul> </script> <script> var data = { title:'My Life', list:['籃球','桌球','游泳','滑輪','讀書'] }; var html = template('test',data); $('.rascal').html(html); </script>
渲染的頁面如下:
2.2:在Javascript中存放模板
在Js中存放模板應該會很少用到,因為在前端領域有一條軍規,結構樣式和行為三者必須分離。如果把模板放在js文件內,會破壞這條規定。
看看例子,知道一下調用的規則。實質上就是一段拼接字符串的過程。
<script type="text/javascript"> var source ="<ul>" + "{{each list as value i}}" + "<li>索引{{i+1}}:{{value}}</li>" + "{{/each}}" + "</ul>"; var render = template.compile(source); var html = render({ list:['籃球','桌球','游泳','滑輪','讀書'] }); $('.rascal').html(html); </script>
2.3:嵌入子模板(include)
嵌套模板跟第一種方法原理相同,只不過在一個模板中調用了另外一個模板而已。
<script id='test' type='text/html'> <h1>My Life</h1> {{include 'list'}} </script> <script id='list' type='text/html'> <ul> {{each list as value i}} <li>索引{{i+1}}:{{value}}</li> {{/each}} </ul> </script> <script> var data = { "list":['籃球','桌球','游泳','滑輪','讀書'] }; var html = template('test',data); $('.rascal').html(html); </script>
3.artTemplate模板引擎使用實戰
artTemplate官網給出的每一個例子其實都已經很好了,可以讓每一個人都很容易的明白。不過我認為唯一的缺點就是,例子中的數據完全都是自己定義的。在實際開發中,用戶看到的每一個商品數據是這樣來的:首先后端攻城獅通過特定語法連接數據庫,然后將從數據庫中獲取的數據轉換成JSON格式,最后前端攻城獅在通過一些方法將JSON數據渲染到頁面上。所以我們的數據不能自己瞎造,而是通過Ajax異步加載。
在我的一篇 淘寶購物車頁面 智能搜索框Ajax異步加載數據 文章中,一開始是使用手寫拼接字符串的方法去拼接字符串,這種方法效率低,容易出錯。后來全部改成了js模板引擎的方法。所以我會以淘寶購物車頁面中智能搜索框Ajax異步加載商品數據的例子來說明artTemplate模板引擎。
先放上一段代碼。主要還是想通過這個簡單的例子說明接下來要探討的問題。
<script id="test" type="text/html"> <h1>{{title}}</h1> <ul> {{each list as value i}} <li>索引{{i+1}} : {{value}}</li> {{/each}} </ul> </script> <script> var data = { title:'My Life', list:['籃球','桌球','游泳','滑輪','讀書'] }; var html = template('test',data); $('.rascal').html(html); </script>
上面代碼中,要注意幾點的就是:
♥ 遍歷表達式中的list必須與腳本中data對象中的list同名,而且遍歷表達式中的list必須是data對象中的一個屬性。循環表達式中,要循環的是每一個data對象中的list數組,而不是data對象,這點很重要。
在這個例子中,data對象中list屬性是一個數組,數組中的每一個值都是簡單數據類型,籃球桌球等。當然,可以往數組中傳入復雜數據類型,如對象。說明這個主要是因為在循環表達式中循環的數據和給template()傳入第二個參數的時候很容易出錯。
♥ 使用template方法時,第一個參數必須是id,而不能是class。
放上一段json數據代碼。

[ [ { "Query":"lan", "Results":[ { "Type":"AS", "Suggests":[ { "Txt":"李寧2016新款男子籃球鞋音速3高幫反彈籃球場地鞋ABAL031", "num":339, "max":764, "discount":200, "label":"liningBas", "shop":"李寧官方網店", "image":"css/images/lining-bas.png", "color":"顏色分類:熒光果粉/木梅紅", "size":"鞋碼:42", "nonDiscount":"¥539.00", "bandCard":"css/images/bankCard.png", "sevenDay":"css/images/sevenDay.png", "guarantee":"css/images/guarantee.png" }, { "Txt":" adidas阿迪達斯籃球男子籃球鞋Regulate", "num":419, "max":18, "discount":120, "label":"adidas", "nonDiscount":"¥539.00", "image":"css/images/adidas.png", "color":"顏色分類:銀金屬/深藏青藍", "shop":"adidas官方旗艦店", "size":"鞋碼:43.5", "bandCard":"css/images/bankCard.png", "sevenDay":"css/images/sevenDay.png", "guarantee":"css/images/guarantee.png" } ] } ] } ], [ { "Query":"音速3", "Results":[ { "Type":"AS", "Suggests":[ { "Txt":"李寧2016新款男子籃球鞋音速3高幫反彈籃球場地鞋ABAL031", "num":339, "max":764, "label":"liningBas", "shop":"李寧官方網店", "image":"css/images/lining-bas.png", "color":"顏色分類:熒光果粉/木梅紅", "size":"鞋碼:42", "nonDiscount":"¥539.00", "bandCard":"css/images/bankCard.png", "sevenDay":"css/images/sevenDay.png", "guarantee":"css/images/guarantee.png" } ] } ] } ] ]
上面代碼中,是一段需要被Ajax異步加載數據的商品數據。
再放上使用一個type="text/html"
的script
標簽存放模板的代碼。

<script id='basketBallShoes' type="text/html"> {{each Suggests as value i}} <div class="mainCommodity"> <div class="shopInfo"> <div class="shopMsg"> <input type="checkbox" name="shopMsg" id='{{value.label}}' class='shopMsg-input' autocomplete="off"> <label for="{{value.label}}">店鋪: <a href="#">{{value.shop}}</a> </div> </div> <div class="commodityInfo"> <ul> <li class='td-chk'> <div class="td-inner"> <input type="checkbox" name='checkbox' autocomplete="off" > </div> </li> <li class='td-item'> <div class="td-inner"> <a href="#" class='desImg'> <img src="{{value.image}}" alt='{{value.Txt}}'> </a> <div class="item-info"> <div class="item-basis-info"> <a href="#">{{value.Txt}}</a> </div> <div class="item-other-info"> <div class="item-other-space"></div> <div class="item-other-list"> <a href="#" title='支持信用卡支付'> <img src="{{value.bandCard}}" alt="支持信用卡支付"> </a> <a href="#" class='sevenDay' title='7天無理由'> <img src="{{value.sevenDay}}" alt="7天無理由"> </a> <a href="#" title='消費者保障服務'> <img src="{{value.guarantee}}" alt="消費者保障服務"> </a> </div> </div> </div> </div> </li> <li class='td-info'> <div class="td-info-msg"> <p>{{value.color}}</p> <p>{{value.size}}</p> </div> </li> <li class='td-price'> <div class="td-inner"> <p class='non-discount'>{{value.nonDiscount}}</p> <p class='discount'>¥<span>{{value.num}}.00</span></p> <div class="promotion"> 賣家促銷 <i class='promotionIcon'></i> </div> <div class="proSlidedown"> <p class='newPro'>賣家促銷:新品大特價</p> <p>優惠:¥200.00</p> </div> </div> </li> <li class='td-amount'> <div class="item-amount"> <a href="#" class='amount-left amount-color'>-</a> <input type="text" name='amountNum' value='1' autocomplete="off"> <a href="#" class="amount-right">+</a> </div> <div class="stock"> {{value.max}} </div> <div class="outNum"> <span class="instr">最多只能購買</span> <span class='stockNum'></span><!-- --><em>件</em> </div> </li> <li class='td-sum'> <em>¥</em><!-- --><span>{{value.num}}</span> </li> <li class='td-operation'> <p><a href="#" class='delete'>刪除</a></p> </li> </ul> </div> </div> {{/each}} </script> <script id="search" type="text/html"> <ul> {{each Suggests as value i}} <li>{{value.Txt}}</li> {{/each}} </ul> </script> <script id='delete' type='text/html'> <div class="undo-wrapper"> <div class="deleteCom"> <p> 成功刪除 <em>1</em> 件寶貝,如果有無,可 <a href="#" class='turnBack'>撤銷本次刪除</a> </p> </div> </div> </script>
上面代碼中是需要被渲染的模板。比手寫拼接字符串簡單很多,並且效率高,錯誤率低。
最后放上js實現相應功能的部分重要代碼。
$.get('search.json',{'Query':$val}, function(data) { for (var i = 0; i < data.length; i++) { //如果值與json中的query字段匹配,動態加載html if ($val === data[i][0].Query) { var results = data[i][0].Results[0]; //js模板引擎 var $html = template('search',results); $('.list').html($html) } } });
這里想說的是給template方法的第二個參數和循環表達式需要被循環的字段。
第一點是給template方法的第二個參數。第二個參數傳入了results,這里的results實質上就是在上面例子中data對象。只不過在JSON數據中results是一個數組。
第二點是在JS模板引擎中。在模板中是這樣寫的:{{each Suggests as value i}},這里的Suggests其實就相當於data對象中的list屬性。在data對象中,list是一個數組,並且每個值都是字符串;而在results數組中,Suggests是一個數組,不過它的每一個值都是復雜數據類型,是對象。如果對數據類型不明白的,可以前往這篇文章:Javascript對象 。
artTemplate使用實戰就介紹完了。在template方法的第二個參數和遍歷表達式中需要被遍歷的數據很容易寫錯,希望同學可以注意這一點。
如果有不明白或者寫錯的地方,可以給我留言。
參考文章
源碼地址:GitHub:Uncle-Keith
轉載請注明出處:http://www.cnblogs.com/Uncle-Keith/p/5932439.html
完。感謝大家的閱讀。