Mustache 使用心得總結

前言:

以前的一個項目裏面就有用到這個前臺的渲染模版,當時挺忙的也沒時間抽空總結一下,恰好上週項目裏又用到這個輕量型的渲染模版,真心感受很好用,所以就總結一下使用心得,算是一個入門級別的指引吧。javascript

1.  Mustache 概述

Mustache是基於JavaScript實現的模版引擎,相似於jQuery Template,可是這個模版更加的輕量級,語法更加的簡單易用,很容易上手。html

2.  Mustache 具體的使用

下面就具體講一下Mustache的使用。在開始講以前,須要先從Git hub上獲取相關的mustache.js文件,獲取文件以後,新建一個解決方案,目錄以下:java

而後就開始具體的使用,首先須要在頁面的head標籤內引用Jquery.js 和Mustache.js兩個腳本文件,主要有如下幾個方面(如下演示的方法均在head標籤中的script代碼塊中):ajax

2.1          簡單的對象綁定展現

l  代碼示例:json

$(function () {  
    var user = { name: "Olive", age: 23, sex: "girl" };  
    var template = "My name is  {{name}} ,I'm  {{age}} ,Sex is {{sex}}";  
    var view = Mustache.render(template, user);  
    $("#user_info").html(view);
}

l  頁面呈現效果:數組

My name is Olive ,I'm 23 ,Sex is girl

l  語法解釋:app

     i.  Mustache的語法很簡單,用兩個大括號標記要綁定的字段便可,「{{}}」;函數

     ii. 大括號內的字段名稱要和Mustache.render方法中的第二個參數中的對象的屬性名一致this

     iii. 主要的渲染方法爲Mustache.render,該方法有兩個參數,第一個爲要渲染的模版,也就是上例中的template,第二個就是數據源也就是上例中的user對象url

2.2          對象數組循環渲染展現

l  代碼示例:

var users = { result: 
   [{ name: "Only", age: 24, sex: "boy" },
    { name: "for", age: 24, sex: "boy" },
    { name: "Olive", age: 23, sex: "girl" }
   ]
};
var template = "<div><table cellpadding=0 cellspacing=0 class='tb' ><tr><td>Name</td><td>Age</td><td>Sex</td></tr>{{#result}}<tr><td>{{name}}</td><td>{{age}}</td><td>{{sex}}</td></tr>{{/result}}</table><div>";
var views = Mustache.render(template, users);
$("#user_info").html(views);

l  頁面呈現效果:

Name	Age	Sex
Only	24	boy
for	24	boy
Olive	23	girl

l  語法解釋:

     i.  對於對象數據Mustache也有其特殊的語法:{{#}}{{/}},若是所給定的數據源是一個對象數組,則可使用該語法,很方便的用來循環展現。

     ii. 其中{{#}}標記表示從該標記之後的內容所有都要循環展現

     iii. {{/}}標記表示循環結束。這種狀況多用於table行的展現。

2.3          判斷對象爲null(false/undefined)展現

l  代碼示例:

var users = { result: 
       [{ name: null, age: 24, sex: "boy" },
        { name: "for", age: 24, sex: "boy" },
        { name: "Olive", age: 23, sex: "girl" }
       ]
};
var template = "<div><table cellpadding=0 cellspacing=0 class='tb' ><tr><td>Name</td><td>Age</td><td>Sex</td></tr>{{#result}}<tr><td>{{#name}}{{name}}</td><td>{{age}}</td><td>{{sex}}{{/name}}</td></tr>{{/result}}</table><div>";
var views = Mustache.render(template, users);
$("#user_info").html(views);

l  頁面呈現效果:

Name	Age	Sex
for	24	boy
Olive	23	girl

l  語法解釋:

        i. 上邊咱們有講到{{#}}{{/}}這樣的語法,除了上邊的循環遍歷以外,它還有另外的一層意思就是判空,若是{{#}}中的值爲null或false或undefine則其標記內的內容則不展示

        ii. 在代碼示例中,users對象中的第一個對象名爲null,因此在展現時,該條用戶信息沒有被展現。

        iii. 有了判空的方法固然還有與之相反的方法{{^}},該方法表示的意思與{{#}}意思相反。

2.4 防止html轉義展現

l  代碼示例:

var user = { name: "<h1>Olive</h1>" };
var template = "my name is {{&name}}";
var view = Mustache.render(template, user);
$("#user_info").html(view);

l  頁面呈現效果:

my name is
Olive

若是不在{{}}中加&,則效果以下:

var user = { name: "<h1>Olive</h1>" };
var template = "my name is {{name}}";
var view = Mustache.render(template, user);
$("#user_info").html(view);

l  頁面呈現效果:

my name is <h1>Olive</h1>

l  語法解釋:

           i. 某些時候,咱們要綁定的數據源中可能會有一些html標記,若是單純的採用{{}}這種方式來綁定的話,默認的會將html標記轉義。爲了解決防止綁定字段中的內容被轉移咱們能夠這樣作{{&}},這樣就能夠防止轉義

 

代碼實例:

例1:

var view = {
    title: 'YZF',
    cacl: function () {
         return 6 + 4;
    }
};
$("#user_info").html(Mustache.render("{{title}} spends {{cacl}}", view));

l  頁面呈現效果:

YZF spends 10

結論:

能夠很明顯的看出Mustache模板的語法,只須要使用{{和}}包含起來就能夠了,裏面放上對象的名稱。

經過本示例也能夠看出,若是指定的屬性爲函數的時候,不會輸出函數裏面的內容,而是先執行函數,而後將返回的結果顯示出來。

例2:

var view = {
    name: "YZF",
    company: "<b>ninesoft</b>"
};
$("#user_info").html(Mustache.render("{{name}} <br /> {{company}} <br />{{{company}}}<br/>{{&company}}", view));

l  頁面呈現效果:

YZF 
<b>ninesoft</b> 
ninesoft
ninesoft

結論:

經過這個示例能夠看出Mustache默認是會將值裏面的html標記進行轉義的,可是有時候咱們並不須要。

因此這裏咱們可使用{{{和}}}包含起來,或者是{{&和}}包含,那麼Mustache就不會轉義裏面的html標記。

例3:

var view = {
    "name": {
         first: "Y",
         second: "zf"
     },
     "age": 21
};
$("#user_info").html(Mustache.render("{{name.first}}{{name.second}} age is {{age}}", view));

l  頁面呈現效果:

Yzf age is 21

結論:

綁定子屬性,僅僅只須要經過.來使用子屬性便可。

例4:

var view = {
    person: false
};
$("#user_info").html(Mustache.render("eff{{#person}}abc{{/person}}", view));

l  頁面呈現效果:

eff

結論:

問題老是不斷,若是咱們還須要可以根據咱們給的值,決定是否渲染某個部分。

那麼如今就能夠解決這個問題,固然還要提示的就是不只僅是false會致使不渲染指定部分。

null,空數組,0,空字符串同樣有效。語法上面比較簡單,就是使用{{#key}} ... {{/key}}

來控制中間的內容。

例5:

var view = {
    stooges: [
       { "name": "Moe" },
       { "name": "Larry" },
       { "name": "Curly" }
    ]
};
$("#user_info").html(Mustache.render("{{#stooges}}{{name}}<br />{{/stooges}}", view));

l  頁面呈現效果:

Moe
Larry
Curly

結論:

僅僅學會上面的方式,大部分地方你都解決了,可是仍是會出現麻煩的地方。

就是循環輸出,若是你一個一個寫,相信會很煩躁,固然Mustache不會讓咱們失望,

它也給出瞭如何循環輸出的方式,這裏是將一個由對象組成的數組輸出,若是咱們

輸出的是數組,就須要使用{{.}}來替代{{name}}。

例6:

var view = {
    "beatles": [
         { "firstname": "Johh", "lastname": "Lennon" },
         { "firstname": "Paul", "lastname": "McCartney" }
     ],
     "name": function () {
          return this.firstname + this.lastname;
      }
};
$("#user_info").html(Mustache.render("{{#beatles}}{{name}}<br />{{/beatles}}", view));

l  頁面呈現效果:

JohhLennon
PaulMcCartney

結論:

循環輸出是有了,可是咱們還想後期進行加工。那麼這個徹底符合你的須要,由於Mustache會將

數組中的值傳遞給你的函數,輸出你函數返回的值。這裏咱們能夠看到最外層是數組,只要在裏面

使用函數那麼外層的數組就會做爲這個函數的參數傳遞進去。

例7:

var view = {
    "name": "Tater",
    "bold": function () {
         return function (text, render) {
             return render(text) + "<br />";
         }
     }
}
$("#user_info").html(Mustache.render("{{#bold}}{{name}}{{/bold}}", view));

l  頁面呈現效果:

Tater

結論:

上面咱們都是用的變量做爲節,那麼咱們如今用函數做爲節,會有什麼效果呢。

它會調用咱們函數返回的函數,將節中間的原始字符串做爲第一個參數,默認

的解釋器做爲第二個參數,那麼咱們就能夠自行加工。

例8:

var view = {
     "repos": []
};
$("#user_info").html(Mustache.render("{{#repos}}{{.}}{{/repos}}{{^repos}}no repos{{/repos}}", view));

l  頁面呈現效果:

no repos

結論:

上面咱們也用節,可是僅僅只能選擇是否輸出某個部分。因此這裏咱們彌補一下。

若是咱們使用了{{^和}}來定義節的話,那麼這個部分只會在裏面的值爲空,null,

空數組,空字符串的時候纔會顯示。那麼咱們就能夠實現了if else的效果了。

例9:

var view = {
    names: [
       { "name": "y" },
       { "name": "z" },
       { "name": "f" }
    ]
};
var base = "<h2>Names</h2>{{#names}}{{>user}}{{/names}}";
var name = "<b>{{name}}</b>";
$("#user_info").html(Mustache.render(base, view, { user: name }));

l  頁面呈現效果:

Names
yzf

結論:

Mustache雖然節約了不少時間,可是咱們定義了不少模板,可是彼此之間沒法互相嵌套使用,也會形成繁瑣。

因此這裏咱們還要介紹如何定義部分模板,用來在其餘模板裏面使用,這裏使用其餘模板的方式僅僅是{{>templetename}}。

最大的不一樣就是Mustache.render方法有了第三個參數。

例10:

HTML中:

其中deptList爲後臺傳過來的LIST集合,想要達到的效果,在<ol>標籤中根據deptList集合來遞歸生動態生成多個<li>元素

<script id="deptListTemplate" type="x-tmpl-mustache">
<ol class="dd-list">
    {{#deptList}}
        <li class="dd-item dd2-item dept-name" id="dept_{{id}}" href="javascript:void(0)" data-id="{{id}}">
            <div class="dd2-content" style="cursor:pointer;">
            {{name}}
            <span style="float:right;">
                <a class="green dept-edit" href="#" data-id="{{id}}" >
                    <i class="ace-icon fa fa-pencil bigger-100"></i>
                </a>
                &nbsp;
                <a class="red dept-delete" href="#" data-id="{{id}}" data-name="{{name}}">
                    <i class="ace-icon fa fa-trash-o bigger-100"></i>
                </a>
            </span>
            </div>
        </li>
    {{/deptList}}
</ol>
</script>

JS:

$(function() {
    var deptList; // 存儲樹形部門列表
    var deptMap = {}; // 存儲map格式的部門信息
    var deptListTemplate = $('#deptListTemplate').html();
    Mustache.parse(deptListTemplate);

    loadDeptTree();

    /*加載部門樹*/
    function loadDeptTree() {
        $.ajax({
            url: "/sys/dept/tree.json",
            success : function (result) {
                //成功返回數據ret爲TRUE
                deptList = result.data;
                var rendered = Mustache.render(deptListTemplate, {deptList: result.data});
                $("#deptList").html(rendered);
                recursiveRenderDept(result.data);
            }
        })
    }

    // 遞歸渲染部門樹
    function recursiveRenderDept(deptList) {
        if(deptList && deptList.length > 0) {
            $(deptList).each(function (i, dept) {
                 deptMap[dept.id] = dept;
                 if (dept.deptList.length > 0) {
                     var rendered = Mustache.render(deptListTemplate, {deptList: dept.deptList});
                     $("#dept_" + dept.id).append(rendered);
                     recursiveRenderDept(dept.deptList);
                 }
            })
        }
    }
});

例11:

Mustache.parse(template);
//其餘代碼
Mustache.render(template,view);

結論:

模板既然有好處,也有壞處。就是編譯模板須要時間,因此在咱們已知會使用某個模板的前提下,咱們能夠預先編譯好這個模板,以便後面的使用。

相關文章
相關標籤/搜索