成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Handlebars—semantic template engine

cyrils / 2960人閱讀

摘要:維護起來將是我們開發(fā)的噩夢。的都是這種的閉合結(jié)構(gòu)的判斷只能判斷和,沒辦法進行這種的邏輯判斷。它的設(shè)定就是如此,它認為邏輯判斷的內(nèi)容不應(yīng)該出現(xiàn)在模板中。因為的輸出默認轉(zhuǎn)義,幾乎所有的模板引擎輸出默認都是轉(zhuǎn)義的,避免攻擊。

概述

剛接觸前端的時候,師傅就給我推薦了Handlebars,自己也蠻喜歡它的語法。到現(xiàn)在,Handlebars都已經(jīng)更新到3.0.3了,是時候重新過一遍文檔了。

引入

要使用Handlebars,首先你得download,然后再頁面引入,就像這樣



如果你使用了模塊化的管理工具,如requirejs、webpack、seajs,不用擔(dān)心。Handlebars是支持amd、cmd規(guī)范的,使用就像這樣

var Handlebars=require("Handlebars");
基本

來一個簡單的例子,向服務(wù)器發(fā)起了一個ajax請求獲取了一個對象數(shù)組,要渲染到頁面上。數(shù)據(jù)格式是這樣的

var data = [
    {
        name: "xxx",
        age: 10
    },
    {
        name: "zzz",
        age: 12
    },
    {
        name: "yyy",
        age: 9
    }
];

首先我們要建立一個模板結(jié)構(gòu),也就是我們的Html,為了展示和邏輯分離,我們不應(yīng)該將模版內(nèi)容放到j(luò)s當(dāng)中,先看下不好的做法:

var $container = $("#container");//容器
var content = "";

data.forEach(function (item) {
    content += "

" + item.name + ":" + item.age + "

"; }); $container.html(content);

當(dāng)Html內(nèi)容一多,各種單引號,雙引號,可讀性、結(jié)構(gòu)性太差。維護起來將是我們開發(fā)的噩夢。
使用Handlebars,首先我們將Html抽出來,就像用script標簽包裹起來,放入我們當(dāng)前的頁面中,就像這樣


    

記得改變type類型,這樣瀏覽器就不會把標簽里的內(nèi)容當(dāng)作js執(zhí)行。然后編寫我們的代碼

var $container = $("#container");//容器
var source = $("#template-user").html();//獲取到html結(jié)構(gòu)
var template = Handlebars.compile(source);//編譯成模板
var html = template(data);//生成完成的html結(jié)構(gòu)
$container.html(html);//插入dom

Handlebars的基本使用就如上了,用{{ }}輸出內(nèi)容。記住了

  

模板最外層的this就是你調(diào)用template方法時傳入的對象

Block

我們使用模板一般都是為了遍歷對象結(jié)構(gòu),然后渲染到頁面上。有人說了如果我就傳遞個字符串進去呢?直接

$container.html(str);

用JBM模板!使用模板最常用的就是if判斷和each遍歷了,下面來詳細講解。

  

Handlebars的block都是這種{{#each}}{{/each}}的閉合結(jié)構(gòu)

if/unless if

Handlebars的if判斷只能判斷true和false,沒辦法進行這種a===3的邏輯判斷。它的設(shè)定就是如此,它認為邏輯判斷的內(nèi)容不應(yīng)該出現(xiàn)在模板中??磦€例子

#template   
{{#if isEdit}}
    

isEdit

{{/if}} {{#if email}}

{{email}}

{{/if}} {{#if num}}

{{num}}

{{/if}} #數(shù)據(jù) var data = { isEdit: true, email: "", num: "0" }; #頁面效果 isEdit 0

Handlebars if在判斷前會做類型轉(zhuǎn)換,如""、undefined、null、0、[]等都會被識別為false。而實際情況下我們都用數(shù)字來標識不同的狀態(tài),碰到這種數(shù)據(jù)我們需要預(yù)處理下,才能渲染哦。

if else
#template    
{{#if isEdit}}
    

isEdit

{{else}}

isNotEdit

{{/if}} #數(shù)據(jù) var data = { isEdit: false }; #頁面效果 isNotEdit

看看多分支是咋子寫的

#template   
{{#if isEdit}}
    

isEdit

{{else if isRead}}

isNotEdit isRead

{{else}}

isNotRead

{{/if}} #數(shù)據(jù) var data = { isEdit: false, isRead: false }; #頁面效果 isNotRead
unless

作用剛好跟if相反,if是true的時候返回,unless是false的時候返回,看例子

#template    
{{#unless isEdit}}
    

isNotEdit

{{else unless isRead}}

isRead

{{else}}

isNotRead

{{/unless}} #數(shù)據(jù) var data = { isEdit: true, isRead:true }; #頁面效果 isNotRead
each 遍歷數(shù)組
#template
{{#each this}}
    

{{this.name}}:{{this.age}}

{{else}}

no data

{{/each}} #數(shù)據(jù) var data = [ { name: "yyy", age: 23 }, { name: "zzz", age: 55 } ]; #頁面效果 yyy:23 zzz:55

each也支持else的判斷。each里面的this是指向單個對象的,這個時候this可以省略不寫,效果是一樣的

{{#each this}}
    

{{name}}:{{age}}

{{/each}}

遍歷數(shù)組的時候一般都會輸出序號,怎么破?

#template
{{#each this}}
    

{{this.name}}:{{this.age}}

{{/each}} #頁面效果 0 yyy:23 1 zzz:55

通過@index或者@key都可以獲得序號,但是序號都是從0開始的,這個比較坑!如果要從1開始,得自己寫個helper處理,真實日了狗了!

遍歷數(shù)組的需要判別是第一個還是最后一個怎么破?

#template
{{#each this}}
    

{{name}}:{{age}} {{#if @first}}first{{/if}} {{#if @last}}last{{/if}}

{{/each}} #頁面效果 yyy:23 first zzz:55 last

通過@first和@last可以判斷是否是數(shù)組的第一個或者最后一個。

  

如果在加上@odd、@even就完美了!

遍歷對象

真實的應(yīng)用場景下,服務(wù)器很可能會返回一個map,就是js當(dāng)中的對象,這個時候我們是不知道有哪些key的,如何遍歷這個map呢?

#template
{{#each this}}
    

{{@key}}:{{this}}

{{/each}} #數(shù)據(jù) var data = { name: "yyy", age: 23 }; #頁面效果 name:yyy age:23

通過@key可以獲取到對象的key名稱。

Html轉(zhuǎn)義

假想這樣一個場景,通過ajax獲取到了一段富文本內(nèi)容,然后展示在頁面中

#template
{{richText}}
#數(shù)據(jù) var data = { richText: "
this is rich text
" }; #頁面效果
this is rich text

這個時候你肯定會想了,真實日了狗了,怎么原樣輸出了,沒有解析成html啊。因為{{richText}}的輸出默認轉(zhuǎn)義Html,幾乎所有的模板引擎輸出默認都是轉(zhuǎn)義Html的,避免xss攻擊。如果你想避免轉(zhuǎn)義,請這樣用

{{{richText}}}
Helpers

列表輸出的時候,如果有時間字段,一般都需要格式化時間,拿到數(shù)據(jù)后我們還得處理

#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}}調(diào)用,維護的成本大大降低。
需要注意的是helper如{{moment arg1 arg2}}的形式最多添加兩個參數(shù)可以被注冊函數(shù)獲取到,如果要添加多個參數(shù),請使用hash的形式

#template

{{query name "arg2" hash1="hash1" hash2="hash2"}}

#數(shù)據(jù) 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就是不轉(zhuǎn)義Html,如果想轉(zhuǎn)義Html直接return內(nèi)容即可。

#template

{{safe}}

#js Handlebars.registerHelper("safe", function () { return new Handlebars.SafeString("
safe string
") }); #頁面效果 safe string
Partials

共享同一個模板內(nèi)容,后端渲染使用的比較多

#template

{{> footer}}

#js Handlebars.registerPartial("footer", function () { return new Handlebars.SafeString("
This is footer
") }); var data = { name: "jacky" }; #頁面效果 This is footer
../

這樣一個數(shù)據(jù)結(jié)構(gòu)渲染到頁面上

#template
{{#each company.prodList}}
    

{{prodName}} {{company.comName}}

{{/each}} #js var data = { company: { comName: "技術(shù)有限公司", prodList: [ { prodName: "產(chǎn)品1" }, { prodName: "產(chǎn)品2" } ] } }; #頁面效果 產(chǎn)品1 產(chǎn)品2

等等好像有點不對勁啊,為啥沒有公司名稱呢?前面說到each里面的this都是指向單個對象的,{{prodName}} {{company.comName}}這種寫法省略了this,還原下

{{#each company.prodList}}
    

{{this.prodName}} {{this.company.comName}}

{{/each}}

知道問題在哪里了吧。怎么破?

{{#each company.prodList}}
    

{{prodName}} {{../company.comName}}

{{/each}}

通過../回到each之外。下面來填另一個經(jīng)典的坑

#template
    {{#each this}}
    • {{#each this}}
    • {{@../index}}-{{@index}} {{this}}
    • {{/each}}
  • {{/each}}
#js var data = [ ["aaa", "bbb", "ccc"], ["ffffd", "eee", "fff"] ]; #頁面效果 0-0 aaa 0-1 bbb 0-2 ccc 1-0 ffffd 1-1 eee 1-2 fff
代碼鏈接

Github

參考

Handlebars

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/64359.html

相關(guān)文章

  • 用100行代碼,完成自己的前端構(gòu)建工具!

    摘要:行代碼,你將擁有一個現(xiàn)代化規(guī)范測試驅(qū)動高延展性的前端構(gòu)建工具。在閱讀前,給大家一個小懸念什么是鏈式操作中間件機制如何讀取構(gòu)建文件樹如何實現(xiàn)批量模板渲染代碼轉(zhuǎn)譯如何實現(xiàn)中間件間數(shù)據(jù)共享。函數(shù)將參數(shù)中的掛載到上,并返回以便于鏈式操作即可。 ES2017+,你不再需要糾結(jié)于復(fù)雜的構(gòu)建工具技術(shù)選型。 也不再需要gulp,grunt,yeoman,metalsmith,fis3。 以上的這些構(gòu)建...

    haitiancoder 評論0 收藏0
  • 使用webpack 構(gòu)建handlebars+jquery+bootstrap的開發(fā)環(huán)境

    摘要:配置文件的編寫在目錄下。當(dāng)然可以根據(jù)其他的解析搭建不同開發(fā)環(huán)境,都是很容易的。 前言 自從webpack 誕生,就開啟了webpack的時代,從其他的老大哥打包工具過度而來,詳情可看: https://github.com/tstrilogy/... 0. 資源 list of loader: https://webpack.github.io/doc... (關(guān)于webpack 所...

    pf_miles 評論0 收藏0
  • 走進Vue-cli源碼,自己動手搭建前端腳手架工具

    摘要:前言前段時間看了一些的源碼,收獲頗深。介紹是一款非常優(yōu)秀的用于迅速構(gòu)建基于的應(yīng)用工具。不影響閱讀源碼,直接忽略掉。引入的包發(fā)送請求的工具。自定義工具用于詢問開發(fā)者。 前言 前段時間看了一些vue-cli的源碼,收獲頗深。本想找個時間更新一篇文章,但是最近事情比較多,沒有時間去整理這些東西。趁這兩天閑了下來,便整理了一下,然后跟大家分享一下。如果小伙伴們讀完之后,跟我一樣收獲很多的話,還...

    Apollo 評論0 收藏0
  • handlebars.js模板引擎

    摘要:基于,可以在中導(dǎo)入模板。利用對象函數(shù)替換對象或者運行函數(shù)支持點語法可以對象等屬性值使用時,直接標簽引入文件。模塊會自動匹配相應(yīng)的數(shù)值,對象或者是函數(shù)。也可以單獨建立一個模板,或者可以用來唯一確定一個模板,是固定寫法,不可或缺。 前言:常用的末班引擎有很多,但寫法都大同小異。handlebars.js就是一個純JS庫,因此你可以向其他腳本一樣用script包起來。調(diào)用內(nèi)部封裝好的功能。 ...

    SimpleTriangle 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<