H5 Handlebars的簡單使用
- 2019 年 11 月 6 日
- 筆記
H5中都是Html,在這裡我們沒有el標籤。所以我們只能藉助模板。好處上面已經介紹了
掃碼關注公眾號,不定期更新幹活

web 開發中,js 解析JSON 是經常的事情。非常繁瑣。handlebars 使用了模版,只要你定義一個模版,提供一個json對象,handlebars 就能吧json對象放到你定的模版中,非常方便好用!
- H5中都是Html,在這裡我們沒有el標籤。所以我們只能藉助模板。好處上面已經介紹了。
H5中循環遍歷
- 第一步:在html中定義模板,將後台的json放在模板里。
<script id="task-table-template" type="text/x-handlebars-template"> {{#each this}}//遍歷循環的格式,相當於foreach <a href="{{link}}">//json中的link必須是{{}}格式 <strong> {{Obj_title}}//同上 </strong> </a> {{/each}} </script> - 第二步:在js中實例化這個模板
var myTemplate = Handlebars.compile($("#task-table-template").html()); - 第三步:將後台json傳進來顯示,並確定模板顯示位置,下面的列子 將模板顯示在class=notice_srcoll的div上
$('.notice_srcoll').html(myTemplate(data.noticeTasklist)); - 這裡提到的json就是我們熟悉的json,給一個列子看看
var data = { users: [ {username: "alan", firstName: "Alan", lastName: "Johnson", email: "[email protected]" }, {username: "allison", firstName: "Allison", lastName: "House", email: "[email protected]" }, {username: "ryan", firstName: "Ryan", lastName: "Carson", email: "[email protected]" } ]}; H5中if else的使用
- handlebar中if else只支援原生態的,也就是只支援true 和 false 的判斷,但是事實上我們的邏輯中很多情況下的判斷並不是僅僅就true和false,這個時候我們這麼辦呢。先看看原生態的if else
{{#if score}} <li> <font> <input type="checkbox" name="you" id="{{id}}" class="regular-checkbox big-checkbox" value="{{id}}" checked disabled/> <label for="{{id}}"></label> </font> <div class="li_div"> <strong> {{name}} </strong> <p>主講老師 {{teacher}} </p> </div> </li> {{else}} <li> <font><input type="checkbox" name="you" id="{{id}}1" class="regular-checkbox big-checkbox" value="{{id}}" /> <label for="{{id}}1"> </label> </font> <div class='li_div'> <strong> "{{name}}" </strong> <p>主講老師 {{teacher}} </p> </div> </li> {{/if}} 這裡的判斷就是說score未undefined null false [] 返回的都是false,在這裡並不能判斷分數大小。這個時候我們通過Handlebars.registerHelper用來定義Helper來對handlebars就醒擴展。
html程式碼
{{#compare age 20}} <tr> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> </tr> {{else}} <tr> <td>?</td> <td>?</td> <td>?</td> </tr> {{/compare}} - js對handlebars擴展
//註冊一個比較大小的Helper,判斷v1是否大於v2 Handlebars.registerHelper("compare",function(v1,v2,options){ if(v1>v2){ //滿足添加繼續執行 return options.fn(this); }else{ //不滿足條件執行{{else}}部分 return options.inverse(this); } }); 這裡需要說明一下,在利用Handlebars.registerHelper註冊事件時,如果後面的function中沒有傳options的話我們就可以直接調用,如果有options的話,我們需要在前面加上#,因為加上options的話是塊級別的Helper。
- 事列一
Handlebars.registerHelper("addOne",function(index,options){ return parseInt(index)+1; }); - 調用
<label for="checkbox-2-{{addOne @index}}"></label> - 事列二
Handlebars.registerHelper("compare",function(v1,v2,options){ if(v1>v2){ //滿足添加繼續執行 return options.fn(this); }else{ //不滿足條件執行{{else}}部分 return options.inverse(this); } }); - 調用
{{#compare age 20}} - 原聲if還支援多級判斷
{{#if name.xxx}},這樣寫就假設name屬性是一個map,檢測name屬性中是否包含xxx屬性。 Helper中options參數
- 這裡參考網上一篇部落格的案列
{{#sort ages id="ages-list" class="con" }} <span>{{@name}}:{{this}}</span> {{/sort}} - 經過編譯後上面這段資訊被分裝在options里了。下面是註冊程式碼
//上面的資訊在下面的options里 Handlebars.registerHelper("sort",function(context,options){ var i = 0,str="<div id="+ options.hash.id +" class="+ options.hash.class +">"; for(;i<context.length;i++){ str+=options.fn(context[i],{data:{name:options.data[i]}}); } str+="</div>"; return str; }); - helper中的options包含了那些資訊?
- data:可以在渲染模板時,將其傳進去,如template(context, {data: data}) 。(//這裡後面會涉及) - hash : 保存寫模板時,可以將一些值以key-value對的形式傳進去,比如上面的div里有ID 和 classs屬性,這兩個都是鍵值對,都會存在options.hash中,這裡我們可以看成是map - fn : 方法,官方解釋說「options.fn的可以被認為是被編譯過的普通handlebars模板,它的調用的執行環境被認為是『this』,所以你可以把this作為執行上下文去調用它」,這裡存放了上面那個div中的閉環體。什麼是閉環體?所謂閉環體就是有開有閉,上面div里那個span就是閉環體,<zzz></zzz>形如這樣的就是閉環體。 - inverse : 給if的block的else來用的.說白了就是給{{else}}使用的。 - 數據源及模板渲染
var template = Handlebars.compile($("#people-template").html()); var temp = {ages:[23,24,56,64]} var result = template(temp,{data:["tom","jak","lili","jim"]}); /*result: <div id="ages-list" class="con"> <span>jak:24</span> <span>lili:56</span> <span>jim:64</span> </div> 模板渲染中用到
var result = template(temp,{data:["tom","jak","lili","jim"]});就是在渲染時傳入data數據.正常情況下傳遞一個json數據,當傳兩個json了,第二個json里的數據就是替換模板中的佔位符的({{@...}}這種寫法的佔位符).str+=options.fn(context[i],{data:{name:options.data[i]}});這句話就是將模板渲染時傳入的數據中的name欄位付給{{@name}}這個佔位符。context[i]就是傳給文中{{this}}也就是相當於{{ages}}的。在渲染時一定要匹配,比如我的數據源是ages那就一定要用ages,那為什麼我上面用的是{{this}},因為我在div中的ages,所以div下面的上下文this指代的就是ages.
仿each寫高級list
- 模板
{{#each comments}} <div class="comment"> <h2>{{subject}}</h2> {{{body}}} </div> {{/each}} - 在上面的模板中看出,我們遍歷出的是div,div本身就是閉環體,都在我們的options.fn中,所以我們的helper就直接遍歷就行了。
Handlebars.registerHelper('each', function(context, options) { var ret = ""; for(var i=0, j=context.length; i<j; i++) { ret = ret + options.fn(context[i]); } return ret; }); 根據這個我們完全可以寫出更加高級的遍歷
模板
{{#list nav}} <a href="{{url}}">{{title}}</a> {{/list}} - helper 不難看出a 是閉環體,也就是我們傳入值,options.fn中就自動有
<a></a>,我們需要做的是加上<ul></ul>,並在每一項上加上<li></li>閉環體。這樣就顯的更加有規格了。這也是官網上提供的。
Handlebars.registerHelper('list', function(context, options) { var ret = "<ul>"; for(var i=0, j=context.length; i<j; i++) { ret = ret + "<li>" + options.fn(context[i]) + "</li>"; } return ret + "</ul>"; }); H5空白處理
- 模板中的空白可以忽略,mustache聲明的兩邊都可以,只需添加一個 ~ 字元即可。寫了這個之後,這一邊的所有空白都會被移除,直到最近的Handlebars表達式或這一邊的非空白字元
{{#each nav ~}} <a href="{{url}}"> {{~#if test}} {{~title}} {{~^~}} Empty {{~/if~}} </a> {{~/each}} { nav: [ {url: 'foo', test: true, title: 'bar'}, {url: 'bar'} ] } - 得出的結果沒有換行,也沒有格式化用的空白符:
<a href="foo">bar</a><a href="bar">Empty</a> 掃碼關注公眾號,不定期更新幹活

# 加入戰隊
微信公眾號

