以前的一個項目裏面就有用到這個前臺的渲染模版,當時挺忙的也沒時間抽空總結一下,恰好上週項目裏又用到這個輕量型的渲染模版,真心感受很好用,所以就總結一下使用心得,算是一個入門級別的指引吧。javascript
Mustache是基於JavaScript實現的模版引擎,相似於jQuery Template,可是這個模版更加的輕量級,語法更加的簡單易用,很容易上手。html
下面就具體講一下Mustache的使用。在開始講以前,須要先從Git hub上獲取相關的mustache.js文件,獲取文件以後,新建一個解決方案,目錄以下:java
而後就開始具體的使用,首先須要在頁面的head標籤內引用Jquery.js 和Mustache.js兩個腳本文件,主要有如下幾個方面(如下演示的方法均在head標籤中的script代碼塊中):ajax
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
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行的展現。
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. 有了判空的方法固然還有與之相反的方法{{^}},該方法表示的意思與{{#}}意思相反。
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> <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);
結論:
模板既然有好處,也有壞處。就是編譯模板須要時間,因此在咱們已知會使用某個模板的前提下,咱們能夠預先編譯好這個模板,以便後面的使用。