摘要:維護起來將是我們開發的噩夢。的都是這種的閉合結構的判斷只能判斷和,沒辦法進行這種的邏輯判斷。它的設定就是如此,它認為邏輯判斷的內容不應該出現在模板中。因為的輸出默認轉義,幾乎所有的模板引擎輸出默認都是轉義的,避免攻擊。
概述
剛接觸前端的時候,師傅就給我推薦了Handlebars,自己也蠻喜歡它的語法。到現在,Handlebars都已經更新到3.0.3了,是時候重新過一遍文檔了。
引入要使用Handlebars,首先你得download,然后再頁面引入,就像這樣
如果你使用了模塊化的管理工具,如requirejs、webpack、seajs,不用擔心。Handlebars是支持amd、cmd規范的,使用就像這樣
var Handlebars=require("Handlebars");基本
來一個簡單的例子,向服務器發起了一個ajax請求獲取了一個對象數組,要渲染到頁面上。數據格式是這樣的
var data = [ { name: "xxx", age: 10 }, { name: "zzz", age: 12 }, { name: "yyy", age: 9 } ];
首先我們要建立一個模板結構,也就是我們的Html,為了展示和邏輯分離,我們不應該將模版內容放到js當中,先看下不好的做法:
var $container = $("#container");//容器 var content = ""; data.forEach(function (item) { content += "" + item.name + ":" + item.age + "
"; }); $container.html(content);
當Html內容一多,各種單引號,雙引號,可讀性、結構性太差。維護起來將是我們開發的噩夢。
使用Handlebars,首先我們將Html抽出來,就像用script標簽包裹起來,放入我們當前的頁面中,就像這樣
記得改變type類型,這樣瀏覽器就不會把標簽里的內容當作js執行。然后編寫我們的代碼
var $container = $("#container");//容器 var source = $("#template-user").html();//獲取到html結構 var template = Handlebars.compile(source);//編譯成模板 var html = template(data);//生成完成的html結構 $container.html(html);//插入dom
Handlebars的基本使用就如上了,用{{ }}輸出內容。記住了
Block模板最外層的this就是你調用template方法時傳入的對象
我們使用模板一般都是為了遍歷對象結構,然后渲染到頁面上。有人說了如果我就傳遞個字符串進去呢?直接
$container.html(str);
用JBM模板!使用模板最常用的就是if判斷和each遍歷了,下面來詳細講解。
if/unless ifHandlebars的block都是這種{{#each}}{{/each}}的閉合結構
Handlebars的if判斷只能判斷true和false,沒辦法進行這種a===3的邏輯判斷。它的設定就是如此,它認為邏輯判斷的內容不應該出現在模板中。看個例子
#template {{#if isEdit}}isEdit
{{/if}} {{#if email}}{{email}}
{{/if}} {{#if num}}{{num}}
{{/if}} #數據 var data = { isEdit: true, email: "", num: "0" }; #頁面效果 isEdit 0
Handlebars if在判斷前會做類型轉換,如""、undefined、null、0、[]等都會被識別為false。而實際情況下我們都用數字來標識不同的狀態,碰到這種數據我們需要預處理下,才能渲染哦。
if else#template {{#if isEdit}}isEdit
{{else}}isNotEdit
{{/if}} #數據 var data = { isEdit: false }; #頁面效果 isNotEdit
看看多分支是咋子寫的
#template {{#if isEdit}}unlessisEdit
{{else if isRead}}isNotEdit isRead
{{else}}isNotRead
{{/if}} #數據 var data = { isEdit: false, isRead: false }; #頁面效果 isNotRead
作用剛好跟if相反,if是true的時候返回,unless是false的時候返回,看例子
#template {{#unless isEdit}}each 遍歷數組isNotEdit
{{else unless isRead}}isRead
{{else}}isNotRead
{{/unless}} #數據 var data = { isEdit: true, isRead:true }; #頁面效果 isNotRead
#template {{#each this}}{{this.name}}:{{this.age}}
{{else}}no data
{{/each}} #數據 var data = [ { name: "yyy", age: 23 }, { name: "zzz", age: 55 } ]; #頁面效果 yyy:23 zzz:55
each也支持else的判斷。each里面的this是指向單個對象的,這個時候this可以省略不寫,效果是一樣的
{{#each this}}{{name}}:{{age}}
{{/each}}
遍歷數組的時候一般都會輸出序號,怎么破?
#template {{#each this}}{{this.name}}:{{this.age}}
{{/each}} #頁面效果 0 yyy:23 1 zzz:55
通過@index或者@key都可以獲得序號,但是序號都是從0開始的,這個比較坑!如果要從1開始,得自己寫個helper處理,真實日了狗了!
遍歷數組的需要判別是第一個還是最后一個怎么破?
#template {{#each this}}{{name}}:{{age}} {{#if @first}}first{{/if}} {{#if @last}}last{{/if}}
{{/each}} #頁面效果 yyy:23 first zzz:55 last
通過@first和@last可以判斷是否是數組的第一個或者最后一個。
遍歷對象如果在加上@odd、@even就完美了!
真實的應用場景下,服務器很可能會返回一個map,就是js當中的對象,這個時候我們是不知道有哪些key的,如何遍歷這個map呢?
#template {{#each this}}{{@key}}:{{this}}
{{/each}} #數據 var data = { name: "yyy", age: 23 }; #頁面效果 name:yyy age:23
通過@key可以獲取到對象的key名稱。
Html轉義假想這樣一個場景,通過ajax獲取到了一段富文本內容,然后展示在頁面中
#template{{richText}}#數據 var data = { richText: "this is rich text" }; #頁面效果this is rich text
這個時候你肯定會想了,真實日了狗了,怎么原樣輸出了,沒有解析成html啊。因為{{richText}}的輸出默認轉義Html,幾乎所有的模板引擎輸出默認都是轉義Html的,避免xss攻擊。如果你想避免轉義,請這樣用
{{{richText}}}Helpers
列表輸出的時候,如果有時間字段,一般都需要格式化時間,拿到數據后我們還得處理
#template {{#each this}}{{name}}:{{addTime}}
{{/each}} #js var data = [ { name: "xxx", addTime: new Date() }, { name: "zzz", addTime: new Date() } ]; data.forEach(function(item){ item.addTime=moment(item.addTime).format("YYYY-MM-DD"); }); #頁面效果 xxx:2015-05-26 zzz:2015-05-26
換個頁面碰到類似的情景,相同的代碼又得寫一面,冗余的代碼太多了,不利于后期維護。怎么破?
#template {{#each this}}{{name}}:{{moment addTime}}
{{/each}} #js Handlebars.registerHelper("moment", function (date, options) { var formatStr = options.hash.format || "YYYY-MM-DD"; return new Handlebars.SafeString(moment(date).format(formatStr)); }); var data = [ { name: "xxx", addTime: new Date() }, { name: "zzz", addTime: new Date() } ];
注冊一個全局的moment,這樣所有的時間格式化,都可以通過{{moment time}}調用,維護的成本大大降低。
需要注意的是helper如{{moment arg1 arg2}}的形式最多添加兩個參數可以被注冊函數獲取到,如果要添加多個參數,請使用hash的形式
#template{{query name "arg2" hash1="hash1" hash2="hash2"}}
#數據 Handlebars.registerHelper("query", function (arg1, arg2, options) { console.log("arg1:" + arg1); console.log("arg2:" + arg2); console.log(options.hash); }); var data = { name: "jacky" }; #控制臺 $ arg1:jacky $ arg2:arg2 $ Object {hash2: "hash2", hash1: "hash1"}
Handlebars.SafeString就是不轉義Html,如果想轉義Html直接return內容即可。
#templatePartials{{safe}}
#js Handlebars.registerHelper("safe", function () { return new Handlebars.SafeString("safe string") }); #頁面效果 safe string
共享同一個模板內容,后端渲染使用的比較多
#template../{{> footer}}
#js Handlebars.registerPartial("footer", function () { return new Handlebars.SafeString("This is footer") }); var data = { name: "jacky" }; #頁面效果 This is footer
這樣一個數據結構渲染到頁面上
#template {{#each company.prodList}}{{prodName}} {{company.comName}}
{{/each}} #js var data = { company: { comName: "技術有限公司", prodList: [ { prodName: "產品1" }, { prodName: "產品2" } ] } }; #頁面效果 產品1 產品2
等等好像有點不對勁啊,為啥沒有公司名稱呢?前面說到each里面的this都是指向單個對象的,{{prodName}} {{company.comName}}這種寫法省略了this,還原下
{{#each company.prodList}}{{this.prodName}} {{this.company.comName}}
{{/each}}
知道問題在哪里了吧。怎么破?
{{#each company.prodList}}{{prodName}} {{../company.comName}}
{{/each}}
通過../回到each之外。下面來填另一個經典的坑
#template
Github
參考Handlebars
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64359.html
摘要:行代碼,你將擁有一個現代化規范測試驅動高延展性的前端構建工具。在閱讀前,給大家一個小懸念什么是鏈式操作中間件機制如何讀取構建文件樹如何實現批量模板渲染代碼轉譯如何實現中間件間數據共享。函數將參數中的掛載到上,并返回以便于鏈式操作即可。 ES2017+,你不再需要糾結于復雜的構建工具技術選型。 也不再需要gulp,grunt,yeoman,metalsmith,fis3。 以上的這些構建...
摘要:配置文件的編寫在目錄下。當然可以根據其他的解析搭建不同開發環境,都是很容易的。 前言 自從webpack 誕生,就開啟了webpack的時代,從其他的老大哥打包工具過度而來,詳情可看: https://github.com/tstrilogy/... 0. 資源 list of loader: https://webpack.github.io/doc... (關于webpack 所...
摘要:前言前段時間看了一些的源碼,收獲頗深。介紹是一款非常優秀的用于迅速構建基于的應用工具。不影響閱讀源碼,直接忽略掉。引入的包發送請求的工具。自定義工具用于詢問開發者。 前言 前段時間看了一些vue-cli的源碼,收獲頗深。本想找個時間更新一篇文章,但是最近事情比較多,沒有時間去整理這些東西。趁這兩天閑了下來,便整理了一下,然后跟大家分享一下。如果小伙伴們讀完之后,跟我一樣收獲很多的話,還...
摘要:基于,可以在中導入模板。利用對象函數替換對象或者運行函數支持點語法可以對象等屬性值使用時,直接標簽引入文件。模塊會自動匹配相應的數值,對象或者是函數。也可以單獨建立一個模板,或者可以用來唯一確定一個模板,是固定寫法,不可或缺。 前言:常用的末班引擎有很多,但寫法都大同小異。handlebars.js就是一個純JS庫,因此你可以向其他腳本一樣用script包起來。調用內部封裝好的功能。 ...
閱讀 3458·2021-11-22 12:00
閱讀 677·2019-08-29 13:24
閱讀 2909·2019-08-29 11:31
閱讀 2595·2019-08-26 14:00
閱讀 3191·2019-08-26 11:42
閱讀 2480·2019-08-23 18:31
閱讀 803·2019-08-23 18:27
閱讀 2851·2019-08-23 16:58