handlebars自定義helper的寫法

  handlebars相對來說算一個輕量級、高性能的模板引擎,因其簡單、直觀、不污染HTML的特性,我我的特別喜歡。另外一方面,handlebars做爲一個logicless的模板,不支持特別複雜的表達式、語句,只內置了一些基本的語法,像if、each這些。惋惜的是就連if都十分弱,只能判斷值是否爲true/false,或轉化後是否爲true/false,不能對值進行比較。不過,handlebars提供了自定義helper的能力,經過自定義helper,能夠實現很是豐富的功能。本篇來總結一下handlebars註冊helper都有哪些方式,以及一些相關的知識。數組

     helper大概能夠分爲兩類,一類是用於格式化輸出數據,使用起來像這樣:{{formatDate date}},官方沒有給起名字,我姑且叫作簡單helper好了。另外一類叫塊級helper,塊級helper有本身的做用域,能夠拿到上下文數據,並能夠定義渲染的內容,能夠發揮的做用就比較大了。經過這兩類helper,handlebars由一個弱邏輯的模板能夠擴展出很強大的功能。經過registerHelper方法,咱們即可以註冊一個helper。下面先看一下簡單helper。less

簡單helper

  簡單helper主要用來對數據進行格式化,例如咱們常常會格式化日期、數字、金額等等。看一個例子就明白了,此處我寫一個把數字進行千分位分割的helper,所謂千分位分割就是把123456789這樣的值格式化爲123,456,789.代碼以下:函數

Handlebars.registerHelper('formatnumber', function(num, options){
          num = num + '';
          return num.replace(/(?=(?!^)(?:\d{3})+(?:\.|$))(\d{3}(\.\d+$)?)/g,',$1');
     });

  而後就能夠在模板中使用:post

{{formatnumber num}}

  registerHelper的第一個參數是helper的名稱,我這裏把它叫作formatnumber,第二個參數是一個函數,該函數傳入的第一個參數就是咱們在使用helper時候的值,如上面的num,最後,函數return的內容就是咱們模板中輸出的內容。此外還會傳入第二個參數options,options是一個對象,包含上下文相關的一些信息,不過在簡單helper中用不到,咱們會下面在塊級helper中詳細說說。性能

     一個簡單helper的定義就是如此簡單,真如其名~測試

塊級helper

  塊級helper的能力就強大不少,能夠實現一些本身想要的迭代器,或者加強判斷語句等。主要依賴的就是這個options參數。下面經過一個例子來講明一下。this

     handlebars的if語句只能進行true/false判斷,若是咱們想判斷一個數字是不是偶數,我這麼寫是不能夠的:{{#if num%2 == 0}},if不支持表達式,也不支持==這樣的操做符。因此要想在模板中判斷偶數,咱們須要定義一個helper。代碼以下:spa

複製代碼
//判斷是不是偶數
Handlebars.registerHelper('if_even', function(value, options) {
    console.log('value:', value); // value: 2
    console.log('this:', this); // this: Object {num: 2}
    console.log('fn(this):', options.fn(this)); // fn(this): 2是偶數
    if((value % 2) == 0) {
        return options.fn(this);
    } else {
        return options.inverse(this);
    }
});
複製代碼

  而後咱們造一個數據,寫在模板中來看看:3d

var data3 = {
    num : 2
}

  模板中:code

複製代碼
{{#if_even num}}
      {{this.num}}是偶數
{{else}}
      {{this.num}}是奇數
{{/if_even}}
複製代碼

  獲得的結果是輸出「2是偶數」。經過在代碼中log出的數據,能夠看到用this能夠取到當前的上下文主體,此處就是咱們的定義好的數據對象了。另一個比較重要的就是options.fn方法,此方法能夠將你傳入的上下文主體編譯到模板,返回編譯後的結果,在helper中,咱們把this傳了進去,因而在模板中也能夠引用到它。最終options.fn返回編譯後的結果:2是偶數。其實你也能夠爲options.fn傳入其餘的上下文對象,好比你要寫一個迭代器,能夠把數組的元素依次傳入。

     此處咱們還看到了另外一個方法,options.inverse,它是取相反的意思,對應了咱們模板中的{{else}}標籤,它會編譯{{else}}中的的內容並返回結果,若是咱們的helper中須要帶else邏輯,用它就能夠了。

     塊級helper在用的時候開頭要加"#",而且要有結束符,就是上面的{{/if_even}}

接收多個參數的helper

  自定義helper能夠傳入多個參數,只要依次寫在registerHelper的函數中就能夠了,看下面一個例子。

  因爲handlebars內置的if語句太弱,有時候咱們須要判斷像==、!=、>、<這樣的邏輯,就必須本身寫定義helper了。這樣的helper須要傳入左右操做數還有操做符,參數不僅一個。下面這個compare是從別的地方抄來的,也是我在項目中用的最多的:

  View Code

  使用的時候是這樣:

複製代碼
{{#compare people.name '==' 'peter'}}
     他的名字是peter
     {{else}}
     他的名字不是peter
 {{/compare}}
複製代碼

  能夠看到在模板中傳入的參數依次對應helper定義中的left、operator、options。同時定義中也是用了options.inverse,用來處理else的邏輯。

爲helper傳入hash參數

  在模板中使用helper的時候,咱們還能夠爲helper傳入一些變量參數,叫作hash參數,在helper中能夠經過options.hash拿到這些參數進行處理。這樣helper的靈活性和可複用性就大大加強了。咱們仍是舉例來講明。

     定義一個名爲list的helper,它的做用是循環輸出數據,並把數據包裹在ul>li標籤中。同時爲了給元素增長不一樣的class,我把class名稱做爲hash來傳入。helper代碼以下:

複製代碼
Handlebars.registerHelper('list', function(items, options) {
    var out = '<ul>';
    for(var i=0, l=items.length; i<l; i++) {
        var item = options.fn(items[i]);
        out = out + '<li class="+options.hash.class+">' + item + '</li>';
    }
    return out + '</ul>';
});
複製代碼

  在模板中,我使用了兩次list,並傳入不一樣的hash值:

{{#list people class="green"}}{{firstName}}-----{{lastName}}{{/list}}
{{#list people class="red"}}{{firstName}}-----{{lastName}}{{/list}}

  定義如下數據作測試:

複製代碼
var data = {
    people: [
        {firstName: "Yehuda", lastName: "Katz"},
        {firstName: "Carl", lastName: "Lerche"},
        {firstName: "Alan", lastName: "Johnson"}
    ]
}
複製代碼

  最終頁面上生成的節點以下所示:

  

  這樣咱們就重用了同一個helper,完成了更加靈活的任務。看到這裏,是否是以爲helper很強大了呢,利用上面這些特性,咱們能夠寫出很是豐富的功能了,足以知足開發需求。

其餘

  另外還有兩點的小知識,補充在此處:

     1. helper的銷燬

     調用Handlebars.unregisterHelper('list')便可銷燬一個helper

     2. 一次註冊多個helper

andlebars.registerHelper({
    foo: function() {},
    bar: function() {}
});

  handlebars做爲一個弱邏輯的靜態模板引擎,自己簡單好用,沒有太多冗餘的東西,同時還提供了強大的擴展性,這也是我喜歡它的緣由。但願經過本篇文章能讓你更多的瞭解handlebars的helper,開始喜歡上它。     

相關文章
相關標籤/搜索