最近在熟悉Handlebars,使用时代码助手还是挺方便的,稍微写了几个示例熟悉下语法。
Handlebars能解析模板字符串,同时利用解析完的模板函数配合输入对象进行转义输出
下面用这个鱼价对象做个示例
var data = {
title: "鱼价表",
fish:[{
name: '蝌蚪',
price: '100',
alive: true
},{
name: "青蛙",
price: '120',
alive: false
},{
name: '竹荚鱼',
price: '150',
alive: true
},{
name: '鲫鱼',
price: '160',
alive: false
},{
name: '雅罗鱼',
price: '240',
alive: true
},{
name: '鲈鱼',
price: '400',
alive: true
}
],
place:[
"池塘",
"大海",
"小河"
],
version: "test 1.05"
}
为了方便,直接在浏览器中编写模板
<script type="text/x-handlebars-template" id="test_expression">
<h2>{{title}}</h2>
script>
这边设置脚本标签type为 text/x-handlebars-template ,主要是为了区别模板代码和普通脚本,实际不设置type属性也可。
JS文件中进行模板的解析和数据内容的输入:
var target = document.getElementById("test_expression").innerHTML
var template = Handlebars.compile(target)
var html = template(data)
document.getElementById("title_content").innerHTML = html
利用Handlebars.compile方法进行模板代码的解析,返回函数对象。将输入数据对象作为参数,利用该函数即可完成转义,之后替换对应的html文本即可。
Handlebars通过代码助手来实现复杂的显示逻辑,按需求加载模板。常用的内置代码模板包括each,if-else等,下面来使用下这两种常用的代码助手。
(1)each
each也是顾名思义在模板中对数据进行一个迭代操作,常见的使用情景为生成table表等。下面用它来输出对应的鱼价表。
首先设置模板代码:
{{#each fish}}
<tr>
<td>{{name}}td>
<td>{{price}}td>
tr>
{{/each}}
Html:
<div>
<table id="table_content">table>
div>
Js:
//利用模板替换table
var table_target = document.getElementById("test_table_template").innerHTML
var template2 = Handlebars.compile(table_target)
var html2 = template2(data)
document.getElementById("table_content").innerHTML = html2
代码助手的使用格式为{{#助手名 输入对象名}}_ 具体内容 {{/助手名}}
,用each遍历模板代码很直观,挺好。
(2)If-else
If判断也是最基本的,其还能与else进行联合使用。下面用改助手进行活鱼的输出。
设置模板代码:
<script type="text/x-handlebars-template" id="test_table_template2">
{{#each fish}}
{{#if alive}}
<tr>
<td>{{name}}</td>
<td>{{price}}</td>
</tr>
{{/if}}
{{/each}}
script>
Html:
<div>
<table id="table_content2">table>
div>
JS:
//利用if-else进行内容筛选
var table_target1 = document.getElementById("test_table_template2").innerHTML
var template3 = Handlebars.compile(table_target1)
var html3 = template3(data)
document.getElementById("table_content2").innerHTML = html3
这部分在模板代码中利用if助手进行alive的判断,最终输出活鱼结果,方便。
可以看出,Handlebar中代码助手可以用来实现模板显示逻辑的编写,但内置助手的功能太过简单,满足不了一般的需求。比如if-else原生助手只能判断输入属性的true和false来进行判断控制,甚至简单的数值比较判断也做不到,这时候就需要自定义代码助手。
下面实践来写一个大于判断助手。
JS中注册自定义代码助手:
//自定义代码助手
Handlebars.registerHelper("bigger", function(x1, x2, options){
if(x1 > x2){
//执行模板渲染
return options.fn(this)
}else{
//跳过
return options.inverse(this)
}
})
可以看到,利用registerHelper
函数进行注册。参数为代码助手名称(也就是模板代码中使用的名称)以及具体方法。在我们的bigger助手中,方法有三个参数,x1与x2是输入,option参数为隐含参数,用来调用Handlebars的处理方法,在模板代码中不用写。
重要方法为option.fn
和option.inverse
,分别为返回上下文和什么都不做跳过。此时this为上下文中内容,如当前迭代数组中对应的迭代值等。
模板代码:
<script type="text/x-handlebars-template" id="test_table_template3">
{{#each fish}}
{{#bigger price 100}}
<tr>
<td>{{name}}</td>
<td>{{price}}</td>
</tr>
{{/bigger}}
{{/each}}
script>
此处意图输出100以上价格的鱼列表,参数设置为price和100,即为上文的x1,x2。之后利用js编译模板输出html即可。
顺便介绍下另一个重要方法Handlebars.SafeString,该方法能返回安全的字符串,防止代码的注入等导致的安全问题,在返回字符串时尽量都选用这个方法。
做一个大写输出的示例:
Handlebars.registerHelper("upper", function(options){
var upperContent = options.fn(this).toUpperCase()
return new Handlebars.SafeString(''
+upperContent+'')
})
这边说的hash功能其实是对自定义代码助手的一种拓展,通过设置属性来实现更广泛的控制功能。比如上文中我们实现了一个大于bigger助手,那么通过hash属性设置就能通过控制属性来实现一个通用的比较代码助手。
Js注册:
//带hash属性
Handlebars.registerHelper("compare", function(x1, x2, options){
var type = options.hash["type"]
if(type == 'up'){
if(x1 > x2){
//执行模板渲染
return options.fn(this)
}else{
//跳过
return options.inverse(this)
}
}else if(type == 'down'){
if(x1 < x2){
//执行模板渲染
return options.fn(this)
}else{
//跳过
return options.inverse(this)
}
}
})
模板代码:
<script type="text/x-handlebars-template" id="test_hash">
{{#each fish}}
{{#compare price 150 type="down"}}
<tr>
<td>{{name}}</td>
<td>{{price}}</td>
</tr>
{{/compare}}
{{/each}}
script>
在函数中使用options.hash就能获取模板中的hash参数。该方法中设置一个type参数,用它来进行大于小于的修改,此时功能是输出价格低于150的鱼价列表。
3.0之后新功能,能从助手代码中接收命名参数。
示例:
<script type="text/x-handlebars-template" id="test_param">
{{#each fish as |fishs fishId|}}
<tr>
<td>{{fishId}}</td>
<td>{{fishs.name}}</td>
<td>{{fishs.price}}</td>
</tr>
{{/each}}
script>
Handlebars能实现模板复用,代码助手实现页面逻辑。
比如Ajax获取JSON数据后解析成对象,直接输入模板即可,减少了页面的重复工作。