Handlebars模板庫淺析

Handlebars模板庫簡單介紹javascript

Handlebars是JavaScript一個語義模板庫,經過對view(模板)和data(ajax請求的數據,通常是json)的分離來快速構建Web模板。它採用"Logic-less template"(無邏輯模版)的思路,在加載時被預編譯(先對view進行編譯生成模板,以後只要把json數據套進去就好了),而不是到了客戶端執行到代碼時再去編譯,這樣能夠保證模板加載和運行的速度。Handlebars兼容Mustache,你能夠在Handlebars中導入Mustache模板。html

Handlebars expressions是handlebars模板中最基本的單元,使用方法是加兩個花括號{{value}}, handlebars模板會自動匹配相應的數值,對象甚至是函數。java

當你想要複用模板的一部分,或者將長模板分割成爲多個模板方便維護時,partials就派上用場了。jquery

經過{{}}取出來的內容(把json的數據取到後,顯示在模板中時),都會通過編碼,也就是說,若是取出的內容中包含html標籤,會被轉碼成純文本,不會被當成html解析,實際上就是作了相似這樣的操做:把<用&lt;替代。這樣作是很好的,既能夠顯示html代碼(轉碼後的html),又能夠避免xss注入(避免顯示的內容是script,或者href,img等有跨站腳本攻擊的標籤)。這個功能在作代碼展現的時候是很是有用的。可是有時候咱們可能須要解析html,不要轉碼,很簡單,把{{}}換成{{{}}}就能夠啦。web

Handlebars模板庫簡單使用ajax

<!DOCTYPE html>
 <html>
   <head>
       <title>Handlebars Expressions Example</title>
   </head>
   <body>
       <h1>Handlebars Expressions Example!</h1>
       <div id="list">
       </div>

       <script type="text/javascript" src="script/jquery.js"></script>     //引入jquery插件
       <script type="text/javascript" src="script/handlebars-1.0.0.beta.6.js"></script>    //引入handlebars模板庫

       <script id="people-template" type="text/x-handlebars-template">      //顯示在頁面上的標準模板
         {{#each people}}
      <div class="person">
                 <h2>{{first_name}} {{last_name}}</h2>
                 <div class="phone">{{phone}}</div>
                 <div class="email"><a href="mailto:{{email}}">{{email}}</a></div>
                 <div class="since">User since {{member_since}}</div>
           </div>
         {{/each}}
       </script>

       <script type="text/javascript">
           $(document).ready(function() {    //頁面加載完成後,執行
    
               var template = Handlebars.compile($("#people-template").html());    express

         //先取到標準模板庫的元素,而後調用html方法,獲得它的內容。因爲它的內容是一個handlebars模板,因此能夠用Handlebars.compile對這個模板進行預編譯。這裏講下jQuery對象html方法:$().html(),第一個匹配元素內容。$().html("chaojidan"),設置全部匹配元素的內容。$().html(function(index,content){  return newContent; }) ,index是匹配元素的位置,content是匹配元素的內容,newContent是替換匹配元素內容的新內容。json


               var data = {   //後臺經過ajax請求到的數據
                 people: [
                     { first_name: "Alan", last_name: "Johnson", phone: "1234567890", email: "alan@test.com", member_since: "Mar 25, 2011" },
                     { first_name: "Allison", last_name: "House", phone: "0987654321", email: "allison@test.com", member_since: "Jan 13, 2011" },
              { first_name: "Nick", last_name: "Pettit", phone: "9836592272", email: "nick@test.com", member_since: "Apr 9, 2009" },
                     { first_name: "Jim", last_name: "Hoskins", phone: "7284927150", email: "jim@test.com", member_since: "May 21, 2010" },
                     { first_name: "Ryan", last_name: "Carson", phone: "8263729224", email: "ryan@test.com", member_since: "Nov 1, 2008" }
                 ]
               };

               $('#list').html(template(data));   //把data對象傳進去,模板會自動去匹配數據。模板中取得是data.people屬性的值。而且對people循環處理,而後把people數組中的每一項進行輸出。最後顯示在頁面中。
           });
       </script>
   </body>
 </html>api

web 開發中,js 解析JSON 是常常的事情。很是繁瑣。handlebars 使用了模版,只要你定義一個模版,提供一個json對象,handlebars 就能把json對象放到你定的模版中,很是方便好用!數組

在模板中也可使用if語句,if 使用方法很簡單,只須要在template中添加{{if}}, 若是有else,也同樣,添加{{else}}。Template中代碼以下:
 {{#each people}}      
   <div class="person">
     <p>{{title}}          
    {{#if author}}         //people數組中的每一項,若是有author屬性,就進入if語句,顯示如下html
            {{author.first_name}} {{author.last_name}}</p>
       {{else}}     //沒有就顯示如下html
            Unknown Author</p>
       {{/if}}
  </div>
{{/each}}

javascript模板引擎偏偏就是爲了幫助咱們有效的組織數據及其展現內容而出現的。和其它的模板使用方式同樣,你須要作以下兩個事情:
1. 建立展現模板      var myTemplate = Handlebars.compile($("#table-template").html());  $("#table-template").html()爲模板內容

2. 將數據解析到模板中     $('#tableList').html(myTemplate(data));    myTemplate(data)爲模板和數據生成的html

咱們可使用with塊去定位咱們須要的celebrity屬性:

若是咱們有一個這樣的上下文對象:

var shoesData = {groupName:"Celebrities", celebrity:{firstName:"Mike", lastName:"Alexander" } };



<script id="shoe-template" type="x-handlebars-template">
  {{groupName}} Group
    {{#with celebrity}}    //進入到celebrity的上下文
      <li>{{firstName}} {{lastName}}</li>
    {{/with}}
</script>

下面的代碼代表了怎樣在Handlebars模板中添加註釋:

{{! 在這其中的註釋表達式不會被輸出 }}
你也可以使使用通常的HTML註釋,可是它們會被輸出到HTML頁面源文件中,就像通常的HTML註釋同樣:

<!-- Regular HTML comments will be in the output -->

Handlebars可使用../來查詢當前上下文中的父路徑的屬性。好比,有一個數據對象以下:

var shoesData = {groupName:"Celebrities", users:[{name:{firstName:"Mike", lastName:"Alexander" }}, {name:{firstName:"John", lastName:"Waters" }} ]};

 
咱們可使用父路徑 ../ 來獲得groupName屬性:

<script id="shoe-template" type="x-handlebars-template">
  {{#users}}     //此種方法也會把users數組中的每一項也輸出
    <li>{{name.firstName}} {{name.lastName}} is in the {{../groupName}} group.</li>   //父路徑下的groupName屬性
  {{/users}}
</script>

unless輔助函數能夠加強if,else。下面的代碼意思:只有當userLoggedIn屬性被檢查爲假值是其中的內容纔會被渲染:

{{#unless userLoggedIn}} Please Log in. {{/unless}}


最後講一下Handlebars最重要的使用方法:

Handlebars.js自定義輔助函數

Handlebars容許咱們添加咱們本身的自定義輔助函數,有了自定義輔助函數,咱們能夠添加任意的Javascript邏輯。咱們須要在全部的Handlebars JS代碼以前註冊自定義輔助函數。自定義輔助函數在Javascript代碼中被建立,而不是在Handlebars模板中。

你能夠建立兩種自定義輔助函數:自定義輔助函數(function helper),它不要使用塊表達式就能運行,自定義塊輔助函數,它須要和一個塊表達式一塊兒運行。

自定義函數輔助函數(function helper)

首先,咱們必須用Handlebars.registerHelper方法註冊一個自定義輔助函數。這個方法接收一個字符串(輔助函數的名字)做爲第一個參數,一個具備任意參數個數的函數做爲第二個參數。

Handlebars.registerHelper ("theNameOfTheHelper", function (theScore) {

  if (theScore >= 90) {
    return "A" ;
  }
  else if (theScore >= 80 && theScore < 90) {
    return "B" ;
  }
  else if (theScore >= 70 && theScore < 80) {
    return "C" ;
  }
  else {
    return "D" ;
  }

});

下面是一個使用咱們剛纔建立的自定義函數輔助函數的Handlebars模板:

<script id="shoe-template" type="x-handlebars-template">
  {{#theNameOfTheHelper score}}
</script>

下面是數據var contextObj = {score:85, userName:"Mike"};

最後,把score=85,傳入到自定義函數中,返回B。因而模板最終結果返回一個"B"。

自定義塊輔助函數

當咱們註冊了一個自定義塊輔助函數時,Handlebars自動在回調函數中添加了一個可選擇對象做爲最後一個參數。這個可選擇對象擁有一個fn方法,一個hash對象,以及一個inverse方法。fn方法接收一個對象(你的數據dataObject[i])做爲自定義塊表達式模板(<div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>)中的上下文。你也能夠傳遞任何數據對象,或者若是你想使用引用模板一樣的上下文,你可使用this(dataObject也就是contextObj)。

咱們使用Handlebars.registerHelper註冊一個userScore的塊輔助函數。注意到參數中的最後一個項目是可選擇對象,它由Handlebars自動添加:

Handlebars.registerHelper ("userScore", function (dataObject, options) {
  var templateWithInterpolatedData = "";

  for (var i = dataObject.length - 1; i >= 0; i--) {     //遍歷dataObject數組
    dataObject[i].score = dataObject[i].score.reduce(function (prev, cur, index, array) {
      return prev + cur;      //數組中的每一項的score屬性是一個數組,把這個數組的每一項相加,結果返回給score屬性
    });  

    //這裏我先介紹一下數組的reduce方法:reduce方法接受兩個參數,一個回調方法,一個初始值。callback回調方法接受4個參數:以前值、當前值、索引值以及數組自己。initialValue(初始值)參數可選,表示初始值。若指定,則看成最初使用的previous值;若是缺省,則使用數組的第一個元素做爲previous初始值,同時current日後排一位,相比有initialValue值少一次迭代。reduce方法,會把數組的每項進行迭代,最終的結果就是最後return的值。好比:var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {return previous + current;});由於沒有初始值,因此previous就是數組的第一項,current就是數組的第二項,index值就是當前值的index(當前是1),array就是原數組[1,2,3,4]。第一次返回1+2=3,第二次previous等於上一次返回的值3,current等於當前值3,返回6,第三次previous等於6,當前值4,返回10.這時數組循環結束,把最後的返回結果10,返回給sum(數組調用reduce的結果)。 最終獲得的結果就是數組的總和。

    // dataObject[i]變成了{firstName: "Kapil", lastName:"Manish", score:201}

    templateWithInterpolatedData += options.fn (c);    

    //將會把對象的數據插入到模板中,也就是把{firstName: "Kapil", lastName:"Manish", score:201}插入到:<div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>,最後疊加成一個字符串

    

  }

  return templateWithInterpolatedData;     //把全部的數據對象插入到模板後生成的html字符串返回。
});

數據:var contextObj = [{firstName: "Kapil", lastName:"Manish", score:[22, 34, 45, 67]}, {firstName: "Bruce", lastName:"Kasparov", score:[10, 34, 67, 90]}];

模板:

<script id="shoe-template" type="x-handlebars-template">
  {{#userScore this}}     //執行userScore(contextObj)
    <div>{{firstName}} {{lastName}}, Your Total Score is <strong>{{score}}</strong> </div>
  {{/userScore}}
</script>

最終的結果:

HTML的輸出結果是:

Bruce Kasparov, Your Total Score is 201

Kapil Manish, Your Total Score is 168

options.inverse方法:

inverse方法在任意塊表達式總被當作else部分來使用。所以,當回調函數中的表達式爲一個真值是你可使用options.fn來返回。可是當回調函數中的表達式爲假值時你可使用options.inverse(去渲染else部分中的內容)。

options.hash對象:

Handlebars表達式不接收任何字符串和變量做爲參數,可是你依然能夠傳遞用空格分開的鍵-值對。例如:

(注意到這裏沒有逗號來分開鍵-值對變量,是空格)

{{#myNewHelper score=30 firstName="Jhonny" lastName="Marco"}}
  Show your HTML content here.
{{/myNewHelper}}
調用擁有鍵-值對做爲參數的Handlebars表達式將會自動添加到輔助函數回調函數的options.hash對象上。所以:

Handlebars.registerHelper ("myNewHelper", function (dataObject, options) {
  //JSON.stringify用於序列化一個json對象爲一個字符串
  console.log(JSON.stringify (options.hash));
  //輸出結果爲:{score:30, firstName:"Jhonny", lastName:"Marco"}

});

 

 

加油!

相關文章
相關標籤/搜索