Handlebars详解使用
按照我个人习惯和学习的总结,最前面放完整代码是比较合适的,故先放出整个代码,后文再一点点讲解。
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/jquery-1.8.3.min.js"></script>
<script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var houdun={
"student":[
{
"name":'郝某人',
"sex":'男',
"age":21
},
{
"name":'杜哈哈',
"sex":'女',
"age":20
},
{
"name":'小郝',
"sex":'女',
"age":22
}
]
}
var myTpl=Handlebars.compile($('#tbody-tr').html());
$('tbody').html(myTpl(houdun));
</script>
</body>
</html>
使用步骤:
第一步,导入jquery和handlebars的js文件
如果没有对应的文件,可以去我的资源下载,地址:https://download.csdn.net/download/qq_43518645/12664585
<script src="../js/jquery-1.8.3.min.js"></script>
<script src="../js/handlebars-v3.0.0.js"></script>
第二步,构造原始代码。如下
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
思考:这一块,tbody标签中的元素这么多,而且在实际成产中,tr标签到底有多少个,是不确定的,这种显示的写法明显是不合适的,所以在此引出循环,each,故下文,我们先说 handlebars中each的使用。
each的简单使用
结合上文思考,我们把代码改变为如下内容:
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
标签中的内容一会我们动态来渲染。
首先,我们模拟一个json数据,用来装配这些tr内容。
<script>
var houdun={
"student":[
{
"name":'郝某人',
"sex":'男',
"age":21
},
{
"name":'杜哈哈',
"sex":'女',
"age":20
},
{
"name":'小郝',
"sex":'女',
"age":22
}
]
}
</script>
动态的标签
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
//注解:
//<script type="text/x-handlebars-template" id="tbody-tr">
//此处type类型一定要指定为text/x-handlebars-template 固定写法,注意一下。
//id="tbody-tr" 起一个id,方便后面引入寻找。
// {{#each xxxx}} xxxx填写的就是要遍历的元素,此处是要遍历模拟的json数据,即student
// {{name}} {{sex}} {{age}} 即取到student中的信息。
实际成产中为了解耦,降低代码耦合度,这种“动态的标签”不会写在当前页面html或者js中,都是独立写出去,再引入,如写入到tpl等等文件中,在此,为了演示方便,入门容易,就暂时写在同一个html或者js中了。在此说明。
上面都是为了代码做准备,其实handlebars中的each使用起来特别简单。
var myTpl=Handlebars.compile($('#tbody-tr').html());
$('tbody').html(myTpl(houdun));
Handlebars.compile() 方法取到内容,此处的Handlebars.compile($(’#tbody-tr’).html())取到的就是下面的内容
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
取到内容后,要把它装配到哪呢?所以需要指定装配一下$(‘tbody’).html(myTpl(houdun)) 此处一个细节需要注意一下,houdun参数需要传入,要不然json数据在哪来没有指定。装配好之后,相当与这样的。
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</tbody>
tbody中就有对应的dom节点,并可以读取到json数据,进行渲染。
效果图
each里的this使用
当json报文为下面这种的时候
var houdun=
[
{
"name":'郝某人',
"sex":'男',
"age":21
},
{
"name":'杜哈哈',
"sex":'女',
"age":20
},
{
"name":'小郝',
"sex":'女',
"age":22
}
]
没有对象的名字,就是拿到一个数据,这个使用,遍历json数据只需要把改为this即可,即修改下面代码。
{{#each this}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
其余代码均不需要改动。
each里的嵌套使用
如果现在json报文为下面这种情况,我们想让数据这样显示:郝某人的爸爸,郝某人的妈妈,郝某人的女朋友,很显然这种情况是存在的,需要用两层each
var houdun=[
{
"name":'郝某人',
"info":["爸爸","妈妈","女朋友"]
},
{
"name":'杜哈哈',
"info":["哥哥","弟弟","男朋友"]
},
{
"name":'小郝',
"info":["爷爷","奶奶","小侄儿"]
}
]
即需要这样的结构
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each this}}
{{#each info}}
<tr>
<td>{{../name}}的{{this}}</td>
</tr>
{{/each}}
{{/each}}
</script>
//可以看到{{../name}} 这个,做的很人性化,name为第一层循环的信息,放在了 第二层循环的位置,使用../退上去,还是很人性化的。
//{{../name}}的{{this}} 这个this 是因为可以看到 json报文 "info":["爸爸","妈妈","女朋友"] 也是因为没有名字,所以使用this
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/jquery-1.8.3.min.js"></script>
<script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each this}}
{{#each info}}
<tr>
<td>{{../name}}的{{this}}</td>
</tr>
{{/each}}
{{/each}}
</script>
<table border="1">
</table>
<script>
var houdun=[
{
"name":'郝某人',
"info":["爸爸","妈妈","女朋友"]
},
{
"name":'杜哈哈',
"info":["哥哥","弟弟","男朋友"]
},
{
"name":'小郝',
"info":["爷爷","奶奶","小侄儿"]
}
]
var myTpl=Handlebars.compile($('#tbody-tr').html());
$('table').html(myTpl(houdun));
</script>
</body>
</html>
效果图
each里的index使用
现在,如果有如下需求:
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
需要遍历一下序号,怎么做呢?其实很简单,使用{{@index}}即可。
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
<tr>
<td>{{@index}}</td>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
可以看到索引下标是从0开始的,如果我们需要从1开始呢?这里呢,也提供了解决办法,我们只需要注册一个帮助模块即可。(我个人的理解,就是注册一个函数,调用这个函数就行)
Handlebars.registerHelper("addOne",function(index,option){
return parseInt(index)+1;
})
//相当于addOne是自己命名的一个函数名字,我们使用这个函数触发即可。
<td>{{addOne @index}}</td>
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/jquery-1.8.3.min.js"></script>
<script src="../js/handlebars-v3.0.0.js"></script>
</head>
<body>
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
<tr>
<td>{{addOne @index}}</td>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
var houdun={
"student":[
{
"name":'郝某人',
"sex":'男',
"age":21
},
{
"name":'杜哈哈',
"sex":'女',
"age":20
},
{
"name":'小郝',
"sex":'女',
"age":22
}
]
}
var myTpl=Handlebars.compile($('#tbody-tr').html());
Handlebars.registerHelper("addOne",function(index,option){
return parseInt(index)+1;
})
$('tbody').html(myTpl(houdun));
</script>
</body>
</html>
效果图
each里的if使用
现在有如下需求,json报文段有的没有name字段,如果没有name字段就不让展示。
var houdun={
"student":[
{
"name":'郝某人',
"sex":'男',
"age":21
},
{
"name":'杜哈哈',
"sex":'女',
"age":20
},
{
"sex":'女',
"age":22
}
]
}
只需要加入if就行{{#if name}}
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
{{#if name}}
<tr>
<td>{{addOne @index}}</td>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/if}}
{{/each}}
</script>
完整代码不贴出来了,就加个if。看效果图。
each里的增强if使用(自定义)
这个在讲解index的使用其实使用过。
就是注册个函数,然后绑定使用函数即可。
Handlebars.registerHelper("compare", function (v1, v2, options) {
if (v1 > v2) {
return options.fn(this);
} else {
return options.inverse(this);
}
})
//这里强调一下细节点:
Handlebars.registerHelper("compare", function (v1, v2, options)
1、 compare是自己起的名字,可以任意起名字,但是起什么名字,就用什么名字调用。
2、 function (v1, v2, options) v1,v2说明是传入2个参数,options参数应该是指定为块标签。(不确定,应该是) 块标签即为 不带options参数,为行级标签。
3、 options.fn(this) 为固定写法,表明如果v1>v2 走if分支,对应的即为走
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
4、 options.inverse(this) 为固定写法,表明如果v1<=v2 走else分支,对应的即为走
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>年龄不大于20</td>
</tr>
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
{{#compare age 20}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{else}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>年龄不大于20</td>
</tr>
{{/compare}}
{{/each}}
</script>
html代码调用处理
这个话题是说什么呢?假如有如下报文段。
var houdun = {
"student": [
{
"name": '郝某人',
"sex": '男',
"age": 21,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
},
{
"name": '杜哈哈',
"sex": '女',
"age": 20,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
},
{
"name": '小郝',
"sex": '女',
"age": 22,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
}
]
}
<script type="text/x-handlebars-template" id="tbody-tr">
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
<td>{{homePage}}</td>
</tr>
{{/each}}
</script>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>主页</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
看下效果图:
这显然不是我们想要的,我们想要的是这种的
那是什么原因造成我们的代码没有展示呢?
其实是因为Handlebars为了安全起见,为了防止外部注入,把代码编译成了源码,这样展示的就是刚才的错误展示,但是有时候我们就是想要用这种超链接,那么怎么办呢?其实很简单
<td>{{{homePage}}}</td>
这里用3个{{{}}}即可,之前为2个{{}}
需要注意的是:此处演示的是超链接,其实只要是h5有意义的标签都存在这个问题,比如
哈哈
,都可以使用3个{{{}}}来进行解决。行级的helper的使用
如果有一段json报文如下:
var houdun = {
"student": [
{
"name": '郝某人',
"sex": 1,
"age": 21,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
},
{
"name": '杜哈哈',
"sex": 0,
"age": 20,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
},
{
"name": '小郝',
"sex": 1,
"age": 22,
"homePage": '<a href="https://www.baidu.com/">百度首页</a>'
}
]
}
性别为0和1,1的时候为男,0的时候为女,那应该怎么做呢?其实之前讲过。
Handlebars.registerHelper("sexA", function (v) {
if(v==1){
return "男";
}else if(v==0){
return "女";
}
})
<td>{{sexA sex}}</td>
可以看到function (v)中没有options参数了,没有即为块标签,其实用法和之前说的一样,比较简单。
效果图
with的使用
with即为进入一个属性当中。
先有如下报文
var houdun = {
"student": [
{
"name": '郝某人',
"sex": 1,
"age": 21,
"hobby":[
{
"name":'篮球'
},
{
"name":'排球'
},
{
"name":'乒乓球'
}
]
},
{
"name": '杜哈哈',
"sex": 0,
"age": 20,
"hobby":[
{
"name":'篮球'
},
{
"name":'排球'
},
{
"name":'乒乓球'
}
]
},
{
"name": '小郝',
"sex": 1,
"age": 22,
"hobby":[
{
"name":'篮球'
},
{
"name":'排球'
},
{
"name":'乒乓球'
}
]
}
]
}
想显示如下效果图
应该怎么做呢?先用with进入hobby中,再使用each进行遍历
<td>
{{#with hobby}}
{{#each this}}
<p>{{name}}</p>
{{/each}}
{{/with}}
</td>
其实不用with也行,使用each循环更简单,不过要知道with这个用法。
<td>
{{#each hobby}}
<p>{{name}}</p>
{{/each}}
</td>
以上就是所有。结束。今天是杜妹的生日,生日快乐。