js模版引擎handlebars.js實用教程

1、爲何選擇Handlebars.js

  據小菜瞭解,對於java開發,涉及到頁面展現時,比較主流的有兩種解決方案:javascript

       1. struts2+vo+el表達式。html

       這種方式,重點不在於struts2,而是vo和el表達式,其基本思想是:根據頁面須要的信息,構造出一個實體,這個實體中包含了界面須要的全部屬性,一般這個實體是由N個表中的字段構成的,俗稱vo。因爲vo的屬性能夠是String、List、Map等等等,又能夠vo套vo,所以這種方式很是靈活,也很是好用。java

       在後臺對vo進行賦值,經過struts2封裝到request中,而後在界面用el表達式,一般是${}、forEach標籤什麼的,便可構造出界面。jquery

       但這種方式小菜卻不是很看好。由於這種利用標籤控制html,依然是把表現和控制混雜在一塊兒,html裏邊混雜了大量el控制標籤,很不美觀。ajax

       固然,小菜不可能由於這麼簡單的理由拒絕這種方式,讀者仔細思考能夠發現,利用el表達式生成html代碼,這是一個在服務器端執行的動做,在服務器端解析完成以後,才發送到客戶端瀏覽器上,這樣作會佔用大量服務器資源,並且速度緩慢。json

         示例代碼:bootstrap

 1 <c:forEach var='bm' items="${contractAuditVo.borrowerModels}">
 2   <table>
 3     <tbody>
 4       <tr>
 5         <td>借款人編號:</td>
 6         <td>
 7           <p>
 8             ${bm.borrowerId }
 9           </p>
10         </td>
11       </tr>
12       <tr>
13         <td>客戶編號:</td>
14         <td>
15           <p>
16             ${bm.customerId }
17           </p>
18         </td>
19       </tr>
20       <tr>
21         <td>曾用名:</td>
22         <td>
23           <p>
24             ${bm.usedName }
25           </p>
26         </td>
27       </tr>
28     </tbody>
29   </table>
30 </c:forEach>

 

 2. Json+ajax+拼html瀏覽器

         這種方法通常是基於ajax請求,要求服務器端返回一個json類型的json字符串,這個json串中包含了界面所需的全部信息,界面拿到json串後,構造出html,完成界面展現。服務器

         小菜推薦這種方法,經過這種方式編寫的頁面,反應速度很是快,用戶體驗很是好。app

         由於服務器端只須要提供一個json串,由客戶端完成解析,所以服務器承受的壓力很小,目前的電腦配置都較高,客戶端的瀏覽器解析js腳本很快,所以頁面體驗效果好。

         解析的過程大體是經過Jquery的each方法,進行遍歷。

         可是小菜利用這種方式時,犯了一個致命的錯誤,小菜是經過原始的拼接html的方式,頁面中寫了大量html+=」<div>」;,這種寫法使頁面變得很是凌亂,幾乎不能夠維護。

         示例代碼:

 1 var contractTextHtml="";
 2 $.each(jsonObject.cl,function(i,n){
 3   
 4   contractTextHtml="";
 5   
 6   //插入合同文本數據
 7   contractTextHtml+="<div title='出借人信息---"+hiddenNull(n.cm.lenderName)+"' style='overflow:auto;padding:5px;'>";
 8   contractTextHtml+="<table class='ui-table ui-table-noborder'>";
 9   contractTextHtml+="<tbody>";
10   contractTextHtml+="<tr><td>合同編號:</td><td><p>"+hiddenNull(n.cm.contractId)+"</p></td></tr>";
11   contractTextHtml+="<tr class='ui-table-split'><td>出借人姓名:</td><td><p>"+hiddenNull(n.cm.lenderName)+"</p></td></tr>";
12   contractTextHtml+="<tr><td>出借人證件類型:</td><td><p>"+hiddenNull(n.cm.lenderIdType)+"</p></td></tr>";
13   contractTextHtml+="<tr class='ui-table-split'><td>出借人證件號:</td><td><p>"+hiddenNull(n.cm.lenderIdNum)+"</p></td></tr>";
14   contractTextHtml+="<tr><td>出借金額:</td><td><p>"+hiddenNull(n.cm.lenderAmount)+"</p></td></tr>";
15   contractTextHtml+="<tr class='ui-table-split'><td>出借人編號:</td><td><p>"+hiddenNull(n.cm.lenderNo)+"</p></td></tr>";
16   contractTextHtml+="<tr><td>出借人銀行賬號:</td><td><p>"+hiddenNull(n.cm.lenderBankAccount)+"</p></td></tr>";
17   contractTextHtml+="<tr class='ui-table-split'><td>撮合編號:</td><td><p>"+hiddenNull(n.cm.makeMatchNo)+"</p></td></tr>";
18   contractTextHtml+="</tbody>";
19   contractTextHtml+="</table>";
20   contractTextHtml+="</div>";
21   $("#textList").append(contractTextHtml);
22 });

   形成這種問題的根本緣由在於拼接html打亂了html原有的層次結構,看不出來哪裏是哪裏,沒有了層次結構的代碼,堆在那裏就像是一坨垃圾。

         el表達式構造html優勢是可以保持html原有格式,js構造html優勢是速度快省資源,爲何咱們不能把兩者的優勢結合在一塊兒呢?這就是Handlebars.js。

         既然要在項目中引入js模版引擎,就必須進行技術選型,嚴格考覈以後,才能夠引入,就好像是木桶效應,不能讓他成爲項目中的短板。

         Handlebars.js是一款基於Jquery的插件,以json對象爲數據源,支持邏輯判斷、循環等操做,同時具備很是好的擴展性,體積60KB左右,通過小菜仔細的分析研究,這是一款不可多得的js模版引擎。 

 

2、如何引入Handlebars.js

  Jquery插件,第一步固然要引用Jquery啦,而後引用Handlebars.js便可,僅僅須要這兩個js文件。

1 <script type="text/javascript" src="script/jquery.js"></script>
2 <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>

 

3、each-基本循環使用方法。

 

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>each-基本循環使用方法 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>each-基本循環使用方法</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16         </tr>
17       </thead>
18       <tbody id="tableList">
19         
20       </tbody>
21     </table>
22     
23     <!--插件引用-->
24     <script type="text/javascript" src="script/jquery.js"></script>
25     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
26     
27     <!--Handlebars.js模版-->
28     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
29     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
30     <script id="table-template" type="text/x-handlebars-template">
31       {{#each student}}
32         <tr>
33           <td>{{name}}</td>
34           <td>{{sex}}</td>
35           <td>{{age}}</td>
36         </tr> 
37       {{/each}}
38     </script>
39     
40     <!--進行數據處理、html構造-->
41     <script type="text/javascript">
42       $(document).ready(function() {
43         //模擬的json對象
44         var data = {
45                     "student": [
46                         {
47                             "name": "張三",
48                             "sex": "0",
49                             "age": 18
50                         },
51                         {
52                             "name": "李四",
53                             "sex": "0",
54                             "age": 22
55                         },
56                         {
57                             "name": "妞妞",
58                             "sex": "1",
59                             "age": 18
60                         }
61                     ]
62                 };
63         
64         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
65         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
66         var myTemplate = Handlebars.compile($("#table-template").html());
67         
68         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
69         $('#tableList').html(myTemplate(data));
70       });
71     </script>
72   </body>
73 </html>

  經過閱讀本例,讀者已經掌握Handlebars.js一個重要特性:循環。#each能夠理解成循環命令,循環的是json對象中的student屬性。對於每次循環,均可以讀出裏邊的name、sex、age屬性。

  

4、each-循環中使用this

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>each-循環中使用this - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>each-循環中使用this</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16         </tr>
17       </thead>
18       <tbody id="tableList">
19         
20       </tbody>
21     </table>
22     
23     <!--插件引用-->
24     <script type="text/javascript" src="script/jquery.js"></script>
25     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
26     
27     <!--Handlebars.js模版-->
28     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
29     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
30     <script id="table-template" type="text/x-handlebars-template">
31       {{#each this}}
32         <tr>
33           <td>{{name}}</td>
34           <td>{{sex}}</td>
35           <td>{{age}}</td>
36         </tr> 
37       {{/each}}
38     </script>
39     
40     <!--進行數據處理、html構造-->
41     <script type="text/javascript">
42       $(document).ready(function() {
43         //模擬的json對象
44         var data = [
45                         {
46                             "name": "張三",
47                             "sex": "0",
48                             "age": 18
49                         },
50                         {
51                             "name": "李四",
52                             "sex": "0",
53                             "age": 22
54                         },
55                         {
56                             "name": "妞妞",
57                             "sex": "1",
58                             "age": 18
59                         }
60                     ];
61         
62         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
63         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
64         var myTemplate = Handlebars.compile($("#table-template").html());
65         
66         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
67         $('#tableList').html(myTemplate(data));
68       });
69     </script>
70   </body>
71 </html>

     不少時候,咱們拿到的json對象,自己就是一個list,並非map,直接就能夠遍歷,不須要#each student這樣指定遍歷某個屬性。

     此時能夠用#each this,表示遍歷當前對象。

     this表示當前上下文,很是靈活,之後還會說起,讀者能夠觸類旁通。

 

5、each嵌套

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>each嵌套 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>each嵌套</h1>
 9     <!--基礎html框架-->
10     <div id="dataList"></div>
11     
12     <!--插件引用-->
13     <script type="text/javascript" src="script/jquery.js"></script>
14     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
15     
16     <!--Handlebars.js模版-->
17     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
18     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
19     <script id="table-template" type="text/x-handlebars-template">
20       {{#each this}}
21         {{#each info}}
22           {{../name}}的{{this}}<br>
23         {{/each}}
24       {{/each}}
25     </script>
26     
27     <!--進行數據處理、html構造-->
28     <script type="text/javascript">
29       $(document).ready(function() {
30         //模擬的json對象
31          var data = [{
32                       "name":"張三",
33                       "info":[
34                         "眼睛",
35                         "耳朵",
36                         "鼻子"
37                       ]
38                     },{
39                       "name":"李四",
40                       "info":[
41                         "爸爸",
42                         "媽媽",
43                         "妻子"
44                       ]
45                     }];
46         
47         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
48         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
49         var myTemplate = Handlebars.compile($("#table-template").html());
50         
51         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
52         $('#dataList').html(myTemplate(data));
53       });
54     </script>
55   </body>
56 </html>

 

          循環嵌套在稍微複雜點的頁面設計中即會涉及,Handlebars.js徹底支持each嵌套,能夠在each中使用each。

          上邊的例子演示了兩個關鍵點:each嵌套的可實現性、如何在each嵌套中讀取父each中的數據。

          例子很簡單,info自己是一個信息列表,是屬於某我的的,咱們先用each遍歷全部的人,而後再遍歷每一個人的info信息,這樣就造成了each嵌套。可是咱們想在內層each中獲取外層each的數據,達到「誰的什麼」這樣的顯示效果。

          顯然,若是直接在內層each中使用{{name}},是取不到任何數據的,由於內層each的上下文是info,而name屬性在表示人的上下文中。

          此時,能夠用{{../name}}從內層each獲取上一級each的name屬性,語法和html的路徑表示同樣,簡單吧?

 

6、循環中使用索引

 

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>關於循環中索引的使用 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>關於循環中索引的使</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>序號</th>
14           <th>姓名</th>
15           <th>性別</th>
16           <th>年齡</th>
17         </tr>
18       </thead>
19       <tbody id="tableList">
20         
21       </tbody>
22     </table>
23     
24     <!--插件引用-->
25     <script type="text/javascript" src="script/jquery.js"></script>
26     <!--注意!這個例子用的是新版本handlebars,舊版本不支持-->
27     <script type="text/javascript" src="script/handlebars-v1.3.0.js"></script>
28     
29     <!--Handlebars.js模版-->
30     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
31     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
32     <script id="table-template" type="text/x-handlebars-template">
33       {{#each student}}
34       <tr>
35         <td>{{addOne @index}}</td>
36         <td>{{name}}</td>
37         <td>{{sex}}</td>
38         <td>{{age}}</td>
39       </tr>
40       {{/each}}
41     </script>
42     
43     <!--進行數據處理、html構造-->
44     <script type="text/javascript">
45       $(document).ready(function() {
46         //模擬的json對象
47          var data = {
48                       "student": [
49                           {
50                               "name": "張三",
51                               "sex": "0",
52                               "age": 18
53                           },
54                           {
55                               "name": "李四",
56                               "sex": "0",
57                               "age": 22
58                           },
59                           {
60                               "name": "妞妞",
61                               "sex": "1",
62                               "age": 19
63                           }
64                       ]
65                   };
66         
67         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
68         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
69         var myTemplate = Handlebars.compile($("#table-template").html());
70         
71         //註冊一個Handlebars Helper,用來將索引+1,由於默認是從0開始的
72         Handlebars.registerHelper("addOne",function(index,options){
73           return parseInt(index)+1;
74         });
75         
76         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
77         $('#tableList').html(myTemplate(data));
78       });
79     </script>
80   </body>
81 </html>

     序號是指:在循環過程當中,當前循環的索引,說白了,就是當前爲第幾回循環,通常從0開始,Handlebars.js中也是如此。

     有什麼用呢?最多見的是在顯示table的時候,給每行加一個序號,清晰的展現出頁面上共有多少條記錄,如上邊的例子。

     除此以外,小菜爲了在循環中區分不一樣的id,剛好須要一個序號,確保id不重複,用過bootstrap的童鞋應該知道,好多事件能夠經過id定位,例如Listgroup控件。

     廢話少說,在Handlebars.js中,能夠經過{{@index}}來獲取當前的索引,也就是說@index這個變量就表明了當前索引。

     在上邊的例子裏,table的序號從0開始不太好,因而註冊了一個Helper,將索引+1。

 

7、Handlebars.js循環中索引(@index)使用技巧(訪問父級索引)

     使用Handlebars.js過程當中,不免會使用循環,好比構造數據表格。而使用循環,又常常會用到索引,也就是獲取當前循環到第幾回了,通常會以這個爲序號顯示在頁面上。

     Handlebars.js中獲取循環索引很簡單,只需在循環中使用{{@index}}便可。

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>Handlebars.js循環中索引(@index)使用技巧 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>Handlebars.js循環中索引(@index)使用技巧</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th></th>
14           <th>姓名</th>
15           <th>性別</th>
16           <th>年齡</th>
17         </tr>
18       </thead>
19       <tbody id="tableList">
20         
21       </tbody>
22     </table>
23     
24     <!--插件引用-->
25     <script type="text/javascript" src="script/jquery.js"></script>
26     <script type="text/javascript" src="script/handlebars-v1.3.0.js"></script>
27     
28     <!--Handlebars.js模版-->
29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
31     <script id="table-template" type="text/x-handlebars-template">
32       {{#each this}}
33         <tr>
34           <td>{{@index}}.</td>
35           <td>{{name}}</td>
36           <td>{{sex}}</td>
37           <td>{{age}}</td>
38         </tr>
39       {{/each}}
40     </script>
41     
42     <!--進行數據處理、html構造-->
43     <script type="text/javascript">
44       var data = [{
45         name: "張三",
46         sex: "",
47         age: 35
48       },{
49         name: "李四",
50         sex: "",
51         age: 23
52       },{
53         name: "甜妞",
54         sex: "",
55         age: 18
56       }];
57       
58       //解析模版
59       var handle = Handlebars.compile($("#table-template").html());
60       //生成html
61       var html = handle(data);
62       //插入到頁面
63       $("#tableList").append(html);
64       
65     </script>
66   </body>
67 </html>
View Code

      雖然用{{@index}}能夠獲取到索引,但遺憾的是,索引是從0開始的。。。這樣讓人看起來很不舒服。所以,咱們可使用一個Helper來讓索引+1,變成從1開始。

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>Handlebars.js循環中索引(@index)使用技巧 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>Handlebars.js循環中索引(@index)使用技巧</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th></th>
14           <th>姓名</th>
15           <th>性別</th>
16           <th>年齡</th>
17         </tr>
18       </thead>
19       <tbody id="tableList">
20         
21       </tbody>
22     </table>
23     
24     <!--插件引用-->
25     <script type="text/javascript" src="script/jquery.js"></script>
26     <script type="text/javascript" src="script/handlebars-v1.3.0.js"></script>
27     
28     <!--Handlebars.js模版-->
29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
31     <script id="table-template" type="text/x-handlebars-template">
32       {{#each this}}
33         <tr>
34           <td>{{addOne @index}}.</td>
35           <td>{{name}}</td>
36           <td>{{sex}}</td>
37           <td>{{age}}</td>
38         </tr>
39       {{/each}}
40     </script>
41     
42     <!--進行數據處理、html構造-->
43     <script type="text/javascript">
44       var data = [{
45         name: "張三",
46         sex: "",
47         age: 35
48       },{
49         name: "李四",
50         sex: "",
51         age: 23
52       },{
53         name: "甜妞",
54         sex: "",
55         age: 18
56       }];
57       
58       //註冊索引+1的helper
59       var handleHelper = Handlebars.registerHelper("addOne",function(index){
60         //返回+1以後的結果
61         return index+1;
62       });
63       //解析模版
64       var handle = Handlebars.compile($("#table-template").html());
65       //生成html
66       var html = handle(data);
67       //插入到頁面
68       $("#tableList").append(html);
69       
70     </script>
71   </body>
72 </html>
View Code

 

      不要覺得這就完事了,這只是通常狀況,小菜還要介紹一個很是特殊的場景。

      假如循環中套了一個循環,在內層循環中如何獲取外層循環的索引呢?

      咱們已經知道,能夠用相似{{../name}}這種語法訪問父級循環中的屬性,可是這樣訪問父級索引是不能夠的,例如:{{../@index}},這樣寫是不正確的。

      咱們能夠經過一個小手段來獲取。

      寫例子以前,小菜多廢話幾句,其實這個很是實用,能夠建立分級的索引,好比1.一、1.2等,也能夠用做特殊的標識,理解成分組。

  1 <!DOCTYPE html>
  2 <html>
  3   <head>
  4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
  5     <title>Handlebars.js循環中索引(@index)使用技巧 - by 楊元</title>
  6   </head>
  7   <body>
  8     <h1>Handlebars.js循環中索引(@index)使用技巧</h1>
  9     <!--基礎html框架-->
 10     <table>
 11       <thead>
 12         <tr>
 13           <th></th>
 14           <th>姓名</th>
 15           <th>性別</th>
 16           <th>年齡</th>
 17         </tr>
 18       </thead>
 19       <tbody id="tableList">
 20         
 21       </tbody>
 22     </table>
 23     
 24     <!--插件引用-->
 25     <script type="text/javascript" src="script/jquery.js"></script>
 26     <script type="text/javascript" src="script/handlebars-v1.3.0.js"></script>
 27     
 28     <!--Handlebars.js模版-->
 29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
 30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
 31     <script id="table-template" type="text/x-handlebars-template">
 32       {{#each this}}
 33         <tr>
 34           <td>{{addOne @index}}</td>
 35           <td>{{name}}</td>
 36           <td>{{sex}}</td>
 37           <td>{{age}}</td>
 38         </tr>
 39         {{#each family}}
 40           <tr>
 41             <td>{{../_index}}.{{@index}}</td>
 42             <td>{{name}}</td>
 43             <td>{{sex}}</td>
 44             <td>{{age}}</td>
 45           </tr>
 46         {{/each}}
 47       {{/each}}
 48     </script>
 49     
 50     <!--進行數據處理、html構造-->
 51     <script type="text/javascript">
 52       var data = [{
 53         name: "張三",
 54         sex: "",
 55         age: 35,
 56         family: [{
 57           name: "張三兒子",
 58           sex: "",
 59           age: 10,
 60         },{
 61           name: "張三妻子",
 62           sex: "",
 63           age: 33,
 64         }]
 65       },{
 66         name: "李四",
 67         sex: "",
 68         age: 23,
 69         family: [{
 70           name: "李四妻子",
 71           sex: "",
 72           age: 23,
 73         }]
 74       },{
 75         name: "甜妞",
 76         sex: "",
 77         age: 18,
 78         family: [{
 79           name: "甜妞媽媽",
 80           sex: "",
 81           age: 40,
 82         },{
 83           name: "甜妞爸爸",
 84           sex: "",
 85           age: 43,
 86         },{
 87           name: "甜妞姥爺",
 88           sex: "",
 89           age: 73,
 90         }]
 91       }];
 92       
 93       //註冊索引+1的helper
 94       var handleHelper = Handlebars.registerHelper("addOne",function(index){
 95         //利用+1的時機,在父級循環對象中添加一個_index屬性,用來保存父級每次循環的索引
 96         this._index = index+1;
 97         //返回+1以後的結果
 98         return this._index;
 99       });
100       //解析模版
101       var handle = Handlebars.compile($("#table-template").html());
102       //生成html
103       var html = handle(data);
104       //插入到頁面
105       $("#tableList").append(html);
106       
107     </script>
108   </body>
109 </html>
View Code

 

8、with-進入到某個屬性(進入到某個上下文環境)

 

  1 <!DOCTYPE html>
  2 <html>
  3   <head>
  4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
  5     <title>with-進入到某個屬性(進入到某個上下文環境) - by 楊元</title>
  6   </head>
  7   <body>
  8     <h1>with-進入到某個屬性(進入到某個上下文環境)</h1>
  9     <!--基礎html框架-->
 10     <table>
 11       <thead>
 12         <tr>
 13           <th>姓名</th>
 14           <th>性別</th>
 15           <th>年齡</th>
 16           <th>興趣愛好</th>
 17         </tr>
 18       </thead>
 19       <tbody id="tableList">
 20         
 21       </tbody>
 22     </table>
 23     
 24     <!--插件引用-->
 25     <script type="text/javascript" src="script/jquery.js"></script>
 26     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
 27     
 28     <!--Handlebars.js模版-->
 29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
 30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
 31     <script id="table-template" type="text/x-handlebars-template">
 32       {{#each this}}
 33         <tr>
 34           <td>{{name}}</td>
 35           <td>{{sex}}</td>
 36           <td>{{age}}</td>
 37           <td>
 38             {{#with favorite}}
 39               {{#each this}}
 40                 <p>{{name}}</p>
 41               {{/each}}
 42             {{/with}}
 43           </td>
 44         </tr> 
 45       {{/each}}
 46     </script>
 47     
 48     <!--進行數據處理、html構造-->
 49     <script type="text/javascript">
 50       $(document).ready(function() {
 51         //模擬的json對象
 52         var data = [
 53                         {
 54                             "name": "張三",
 55                             "sex": "0",
 56                             "age": 18,
 57                             "favorite":
 58                             [
 59                               {
 60                                 "name":"唱歌"
 61                               },{
 62                                 "name":"籃球"
 63                               }
 64                             ]
 65                         },
 66                         {
 67                             "name": "李四",
 68                             "sex": "0",
 69                             "age": 22,
 70                             "favorite":
 71                             [
 72                               {
 73                                 "name":"上網"
 74                               },{
 75                                 "name":"足球"
 76                               }
 77                             ]
 78                         },
 79                         {
 80                             "name": "妞妞",
 81                             "sex": "1",
 82                             "age": 18,
 83                             "favorite":
 84                             [
 85                               {
 86                                 "name":"電影"
 87                               },{
 88                                 "name":"旅遊"
 89                               }
 90                             ]
 91                         }
 92                     ];
 93         
 94         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
 95         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
 96         var myTemplate = Handlebars.compile($("#table-template").html());
 97         
 98         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
 99         $('#tableList').html(myTemplate(data));
100       });
101     </script>
102   </body>
103 </html>

  在循環每名學生時,學生的favorite屬性並非一個普通的字符串,而又是一個json對象,確切的說是一個list,咱們須要把學生的愛好所有取出來。

     這時候就須要with命令,這個命令可讓當前的上下文進入到一個屬性中,{{#with favorite}}表示進入到favorite屬性的上下文中,而favorite屬性中又是一個list,所以能夠用{{#each this}}進行遍歷,表示遍歷當前上下文環境,對於每次遍歷,都是map結構,取name屬性,最終拿到全部興趣愛好。

 

9、with-終極this應用

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>with-終極this應用 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>with-終極this應用</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16           <th>興趣愛好</th>
17         </tr>
18       </thead>
19       <tbody id="tableList">
20         
21       </tbody>
22     </table>
23     
24     <!--插件引用-->
25     <script type="text/javascript" src="script/jquery.js"></script>
26     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
27     
28     <!--Handlebars.js模版-->
29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
31     <script id="table-template" type="text/x-handlebars-template">
32       {{#each this}}
33         <tr>
34           <td>{{name}}</td>
35           <td>{{sex}}</td>
36           <td>{{age}}</td>
37           <td>
38             {{#with favorite}}
39               {{#each this}}
40                 <p>{{this}}</p>
41               {{/each}}
42             {{/with}}
43           </td>
44         </tr> 
45       {{/each}}
46     </script>
47     
48     <!--進行數據處理、html構造-->
49     <script type="text/javascript">
50       $(document).ready(function() {
51         //模擬的json對象
52         var data = [
53                         {
54                             "name": "張三",
55                             "sex": "0",
56                             "age": 18,
57                             "favorite":
58                             [
59                               "唱歌",
60                               "籃球"
61                             ]
62                         },
63                         {
64                             "name": "李四",
65                             "sex": "0",
66                             "age": 22,
67                             "favorite":
68                             [
69                               "上網",
70                               "足球"
71                             ]
72                         },
73                         {
74                             "name": "妞妞",
75                             "sex": "1",
76                             "age": 18,
77                             "favorite":
78                             [
79                               "電影",
80                               "旅遊"
81                             ]
82                         }
83                     ];
84         
85         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
86         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
87         var myTemplate = Handlebars.compile($("#table-template").html());
88         
89         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
90         $('#tableList').html(myTemplate(data));
91       });
92     </script>
93   </body>
94 </html>

     本例和上例不一樣之處在於favorite屬性中再也不是map項,而是普通字符串,所以對於每一個項,能夠直接用{{this}}讀取,this表明當前字符串。

     因此說,this很是靈活,讀者必定要大膽發揮想象力。 

 

10、if-判斷的基本用法

 

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>if-判斷的基本用法 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>if-判斷的基本用法</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16         </tr>
17       </thead>
18       <tbody id="tableList">
19         
20       </tbody>
21     </table>
22     
23     <!--插件引用-->
24     <script type="text/javascript" src="script/jquery.js"></script>
25     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
26     
27     <!--Handlebars.js模版-->
28     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
29     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
30     <script id="table-template" type="text/x-handlebars-template">
31       {{#each student}}
32         {{#if name}}
33           <tr>
34             <td>{{name}}</td>
35             <td>{{sex}}</td>
36             <td>{{age}}</td>
37           </tr>
38         {{/if}}
39       {{/each}}
40     </script>
41     
42     <!--進行數據處理、html構造-->
43     <script type="text/javascript">
44       $(document).ready(function() {
45         //模擬的json對象
46         var data = {
47                     "student": [
48                         {
49                             "name": "張三",
50                             "sex": "0",
51                             "age": 18
52                         },
53                         {
54                             "sex": "0",
55                             "age": 22
56                         },
57                         {
58                             "name": "妞妞",
59                             "sex": "1",
60                             "age": 18
61                         }
62                     ]
63                 };
64         
65         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
66         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
67         var myTemplate = Handlebars.compile($("#table-template").html());
68         
69         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
70         $('#tableList').html(myTemplate(data));
71       });
72     </script>
73   </body>
74 </html>

     在遍歷student時,因爲數據缺失,並非每個學生都有name屬性,咱們不想顯示沒有name屬性的學生,這時就須要if來作判斷。

     {{#if name}}能夠用來判斷當前上下文中有沒有name屬性,實際上,它是嘗試去讀取name屬性,若是返回的爲undefined、null、""、[]、false任意一個,都會致使最終結果爲假。

     if還支持多層次讀取,例如:{{#if name.xxx}},這樣寫就假設name屬性是一個map,檢測name屬性中是否包含xxx屬性。 

 

11、因爲if功力不足引出的Helper

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>因爲if功力不足引出的Helper - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>因爲if功力不足引出的Helper</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16         </tr>
17       </thead>
18       <tbody id="tableList">
19         
20       </tbody>
21     </table>
22     
23     <!--插件引用-->
24     <script type="text/javascript" src="script/jquery.js"></script>
25     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
26     
27     <!--Handlebars.js模版-->
28     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
29     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
30     <script id="table-template" type="text/x-handlebars-template">
31       {{#each student}}
32         {{#if name}}
33           {{#compare age 20}}
34             <tr>
35               <td>{{name}}</td>
36               <td>{{sex}}</td>
37               <td>{{age}}</td>
38             </tr>
39           {{else}}
40             <tr>
41               <td>?</td>
42               <td>?</td>
43               <td>?</td>
44             </tr>
45           {{/compare}}
46         {{/if}}
47       {{/each}}
48     </script>
49     
50     <!--進行數據處理、html構造-->
51     <script type="text/javascript">
52       $(document).ready(function() {
53         //模擬的json對象
54         var data = {
55                     "student": [
56                         {
57                             "name": "張三",
58                             "sex": "0",
59                             "age": 23
60                         },
61                         {
62                             "sex": "0",
63                             "age": 22
64                         },
65                         {
66                             "name": "妞妞",
67                             "sex": "1",
68                             "age": 18
69                         }
70                     ]
71                 };
72         
73         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
74         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
75         var myTemplate = Handlebars.compile($("#table-template").html());
76         
77         //註冊一個比較大小的Helper,判斷v1是否大於v2
78         Handlebars.registerHelper("compare",function(v1,v2,options){
79           if(v1>v2){
80             //知足添加繼續執行
81             return options.fn(this);
82           }else{
83             //不知足條件執行{{else}}部分
84             return options.inverse(this);
85           }
86         });
87         
88         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
89         $('#tableList').html(myTemplate(data));
90       });
91     </script>
92   </body>
93 </html>

         不少時候,咱們須要更加複雜的if判斷邏輯,顯然默認的if不能知足咱們的需求。

         本例中,利用Handlebars.js中Helper強大的擴展性,定義了一個compare,它用來比較兩個數的大小,若是第一個數大於第二個數,知足條件繼續執行,不然執行{{else}}部分。

         Handlebars.registerHelper用來定義Helper,它有兩個參數,第一個參數是Helper名稱,第二個參數是一個回調函數,用來執行核心業務邏輯。本例中的函數,有三個參數,其中前兩個參數是須要比較的兩個數,第三個參數是固定的,就叫options,若是加了該參數,就說明這個Helper是一個Block,塊級別的Helper,有必定的語法結構,調用的時候加#號,就像if那樣。

         關於options的使用,小菜所瞭解的就是這種用法,return options.fn(this);表示知足條件繼續執行,也就是執行{{#compare }}和{{else}}之間的代碼;return options.inverse(this);表示不知足條件,也就是執行{{else}}和{{/compare}}之間的代碼。

         因爲這是一個塊級別的Helper,因此調用要加#,例如:{{#compare age 20}},其中的age就是當前上下文中讀取到的年齡,20是小菜隨便寫的值,意思是隻要age比20大,就顯示,不然全顯示?。

         讀者能夠看出,Helper中寫的能夠是任何js代碼,如今想一想,就知道Handlebars有多靈活了吧!!

 

12、另外一種Helper用法

 

  1 <!DOCTYPE html>
  2 <html>
  3   <head>
  4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
  5     <title>另外一種Helper用法 - by 楊元</title>
  6   </head>
  7   <body>
  8     <h1>另外一種Helper用法</h1>
  9     <!--基礎html框架-->
 10     <table>
 11       <thead>
 12         <tr>
 13           <th>姓名</th>
 14           <th>性別</th>
 15           <th>年齡</th>
 16         </tr>
 17       </thead>
 18       <tbody id="tableList">
 19         
 20       </tbody>
 21     </table>
 22     
 23     <!--插件引用-->
 24     <script type="text/javascript" src="script/jquery.js"></script>
 25     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
 26     
 27     <!--Handlebars.js模版-->
 28     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
 29     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
 30     <script id="table-template" type="text/x-handlebars-template">
 31       {{#each student}}
 32         {{#if name}}
 33           {{#compare age 20}}
 34             <tr>
 35               <td>{{name}}</td>
 36               <td>{{transformat sex}}</td>
 37               <td>{{age}}</td>
 38             </tr>
 39           {{else}}
 40             <tr>
 41               <td>?</td>
 42               <td>?</td>
 43               <td>?</td>
 44             </tr>
 45           {{/compare}}
 46         {{/if}}
 47       {{/each}}
 48     </script>
 49     
 50     <!--進行數據處理、html構造-->
 51     <script type="text/javascript">
 52       $(document).ready(function() {
 53         //模擬的json對象
 54         var data = {
 55                     "student": [
 56                         {
 57                             "name": "張三",
 58                             "sex": "0",
 59                             "age": 23
 60                         },
 61                         {
 62                             "name": "李四",
 63                             "sex": "0",
 64                             "age": 18
 65                         },
 66                         {
 67                             "name": "妞妞",
 68                             "sex": "1",
 69                             "age": 21
 70                         }
 71                     ]
 72                 };
 73         
 74         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
 75         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
 76         var myTemplate = Handlebars.compile($("#table-template").html());
 77         
 78         //註冊一個比較大小的Helper,判斷v1是否大於v2
 79         Handlebars.registerHelper("compare",function(v1,v2,options){
 80           if(v1>v2){
 81             //知足添加繼續執行
 82             return options.fn(this);
 83           }else{
 84             //不知足條件執行{{else}}部分
 85             return options.inverse(this);
 86           }
 87         });
 88         
 89         //註冊一個翻譯用的Helper,0翻譯成男,1翻譯成女
 90         Handlebars.registerHelper("transformat",function(value){
 91           if(value==0){
 92             return "";
 93           }else if(value==1){
 94             return "";
 95           }
 96         });
 97         
 98         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
 99         $('#tableList').html(myTemplate(data));
100       });
101     </script>
102   </body>
103 </html>

  小菜剛剛提到過,帶options參數的Helper是塊級別的,而不帶的,至關於行內級別的Helper。

       從例子一開始,性別就是用0、1代碼表示的,但實際狀況下咱們須要轉換成漢字,transformat這個Helper須要一個參數,根據不一樣的代碼,返回男女,這樣調用{{transformat sex}},其中sex是從當前上下文中讀取的性別代碼。

 

十3、關於HTML編碼

 

 1 <!DOCTYPE html>
 2 <html>
 3   <head>
 4     <META http-equiv=Content-Type content="text/html; charset=utf-8">
 5     <title>關於HTML編碼 - by 楊元</title>
 6   </head>
 7   <body>
 8     <h1>關於HTML編碼</h1>
 9     <!--基礎html框架-->
10     <table>
11       <thead>
12         <tr>
13           <th>姓名</th>
14           <th>性別</th>
15           <th>年齡</th>
16           <th>我的主頁</th>
17         </tr>
18       </thead>
19       <tbody id="tableList">
20         
21       </tbody>
22     </table>
23     
24     <!--插件引用-->
25     <script type="text/javascript" src="script/jquery.js"></script>
26     <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>
27     
28     <!--Handlebars.js模版-->
29     <!--Handlebars.js模版放在script標籤中,保留了html原有層次結構,模版中要寫一些操做語句-->
30     <!--id能夠用來惟一肯定一個模版,type是模版固定的寫法-->
31     <script id="table-template" type="text/x-handlebars-template">
32       {{#each student}}
33         <tr>
34           <td>{{name}}</td>
35           <td>{{sex}}</td>
36           <td>{{age}}</td>
37           {{#compare age 20}}
38             <td>{{homePage}}</td>
39           {{else}}
40             <td>{{{homePage}}}</td>
41           {{/compare}}
42         </tr> 
43       {{/each}}
44     </script>
45     
46     <!--進行數據處理、html構造-->
47     <script type="text/javascript">
48       $(document).ready(function() {
49         //模擬的json對象
50         var data = {
51                     "student": [
52                         {
53                             "name": "張三",
54                             "sex": "0",
55                             "age": 18,
56                             "homePage":"<a href='javascript:void(0);'>張三的我的主頁</a>"
57                         },
58                         {
59                             "name": "李四",
60                             "sex": "0",
61                             "age": 22,
62                             "homePage":"<a href='javascript:void(0);'>李四的我的主頁</a>"
63                         },
64                         {
65                             "name": "妞妞",
66                             "sex": "1",
67                             "age": 19,
68                             "homePage":"<a href='javascript:void(0);'>妞妞的我的主頁</a>"
69                         }
70                     ]
71                 };
72         
73         //註冊一個Handlebars模版,經過id找到某一個模版,獲取模版的html框架
74         //$("#table-template").html()是jquery的語法,不懂的童鞋請惡補。。。
75         var myTemplate = Handlebars.compile($("#table-template").html());
76         
77         //註冊一個比較數字大小的Helper,有options參數,塊級Helper
78         Handlebars.registerHelper("compare",function(v1,v2,options){
79           //判斷v1是否比v2大
80           if(v1>v2){
81             //繼續執行
82             return options.fn(this);
83           }else{
84             //執行else部分
85             return options.inverse(this);
86           }
87         });
88         
89         //將json對象用剛剛註冊的Handlebars模版封裝,獲得最終的html,插入到基礎table中。
90         $('#tableList').html(myTemplate(data));
91       });
92     </script>
93   </body>
94 </html>

     經過{{}}取出來的內容,都會通過編碼,也就是說,若是取出的內容中包含html標籤,會被轉碼成純文本,不會被當成html解析,實際上就是作了相似這樣的操做:把<用&lt;替代。

     這樣作是很好的,既能夠顯示html代碼,又能夠避免xss注入。這個功能在作代碼展現的時候是很是有用的。

     可是有時候咱們可能須要解析html,不要轉碼,很簡單,把{{}}換成{{{}}}就能夠啦。

     本例中,年齡大於20的童鞋我的主頁被編碼,直接展現出來;而年齡小於20的童鞋,我的主頁被當成html解析,顯示的是一個超連接。

 

十4、結束語

     有了這些功能,[ajax+json+Handlebars]替代[vo+el表達式]不成問題,新時代的曙光已經來臨,最佳解決方案在此,您還等什麼?

     教程到此結束。。。祝讀者學習愉快。。。

 

轉:http://www.cnblogs.com/iyangyuan/p/3471379.html

相關文章
相關標籤/搜索