示例在最后;
官网地址:http://handlebarsjs.com/
参考地址1:http://blog.csdn.net/fengqingtao2008/article/details/52711858
参考地址2:https://segmentfault.com/a/1190000008367747
1、如何引入Handlebars.js
首选要引入JQuery插件,其次在引用Handlebars.js即可,仅仅需要这两个js文件。
2、基本语法
handlebarsjs 是模块中的最基本的单元,使用时用两个花括号{{ }} 包裹。eg:{{ value }} ,handlebars模块会自动匹配相应的数值,对象或者是函数。
<div class="demo">
<h1>{{name}}</h1>
<p>{{content}}</p>
</div>
也可以单独建立一个模板,id(或者class)可以用来唯一确定一个模板,type是固定写法,不可或缺。通过<script>标签包裹handlebars表达式传递模板给浏览器。
<script id="tpl" type="text/x-handlebars-template">
<div class="demo">
<h1>{{title}}</h1>
<p>{{content.title}}</p>
</div>
</script>
3、预编译模板
js 中使用handelbars.compile()预编译模板 :
//用jquery获取模板
var tpl = $("#tpl").html();
//原生方法
var source = document.getElementById('#tpl').innerHTML;
//预编译模板
var template = Handlebars.compile(source);
//模拟json数据
var context = { name: "zhaoshuai", content: "learn Handlebars"};
//匹配json内容
var html = template(context);
//输入模板
$(body).html(html);
通过解析context处理handlebars模板获取HTML内容:
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);
输出html:
<div class="entry">
<h1>My New Post</h1>
<div class="body">
This is my first post!
</div>
</div>
4、blocks表达式
- 表达式的后面跟一个
#
表示blocks; - 通过
{{/表达式}}
来结束Blocks; - 如果当前表达式是 数组则handelbars会展开数组。并将blocks的上下文设为数组元素);
<ul>
{{#programme}}
<li>{{language}}</li>
{{/programme}}
</ul>
//对应json数据
{
programme: [
{language: "JavaScript"},
{language: "HTML"},
{language: "CSS"}
]
}
//渲染后:
<ul>
<li>JavaScript</li>
<li>HTML</li>
<li>CSS</li>
</ul>
5、Handelbars内置表达式(Block helper)
- each:
利用{{#each name}}来遍历列表块的内容,
用this来引用遍历的元素,指数组里的每一个元素。 name 是数组。
<ul>
{{#each name}}
<li>{{this}}</li>
{{/each}}
</ul>
//对应json是:
{
name: ["html","css","javascript"]
};
//编译后:
<ul>
<li>JavaScript</li>
<li>HTML</li>
<li>CSS</li>
</ul>
- if else :
指定条件渲染dom;
如果 {{ #if list }},即if后的参数存在, 则渲染{{ #else }}后面的语句;
否则将不会渲染都dom,将执行{{ else }}后的error语句;
{{#if list}}
<ul id="list">
{{#each list}}
<li>{{this}}</li>
{{/each}}
</ul>
{{else}}
<p>{{error}}</p>
{{/if}}
//对应的json:
var data = {
info:['HTML5','CSS3',"WebGL"],
"error":"数据取出错误"
}
unless
{{ #unless }}反向的一个if语句;unless后的参数 不存在 为false时,渲染dom;with
{{#with}}一般情况下,Handlebars模板会在编译的阶段的时候进行context传递 和 赋值。
使用with的方法,我们可以将context转移到数据的一个section里面(如果你的数据包含section)。
这个方法在操作复杂的template时候非常有用。
即:在使用json数据较为复杂时,我们用这种方式来确定模板里填写的内容是json对象的哪一个部分!
<div class="entry">
<h1>{{title}}</h1>
{{#with author}}
<h2>By {{firstName}} {{lastName}}</h2>
{{/with}}
</div>
//对应json数据:
{
title: "My first post!",
author: {
firstName: "Charles",
lastName: "Jolley"
}
}
6、handlebar的注释(comments)
写法:
{{! handlebars comments }}
7、handlebar的访问(path)
可以通过 . 语法访问子属性;
也可以通过 ../ 来访问父级属性。
<h1>{{author.id}}</h1>
{{#with person}}
<h1>{{../company.name}}</h1>
{{/with}}
8、自定义helper
用Handlebars.registerHelper ( )方法来注册一个helper
9、handelbars的jquery插件
(function($) {
var compiled = {};
$.fn.handlebars = function(template, data){
if (template instanceof jQuery) {
template = $(template).html();
}
compiled[template] = Handlebars.compile(template);
this.html(compiled[template](data));
};
})(jQuery);
$('#content').handlebars($('#template'), { name: "Alan" });
10、示例
(1)、each-基本循环使用方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handlebars模板运用</title>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>each-基本循环使用方法</h1>
<!--基础html框架-->
<table>
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody id="tableList">
</tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">
{{#each student}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
<!--进行数据处理、html构造-->
<script type="text/javascript">
$(document).ready(function() {
//模拟的json对象
var data = {
"student": [
{
"name": "王五",
"sex": "男",
"age": 28
},
{
"name": "李四",
"sex": "女",
"age": 30
},
{
"name": "妞妞",
"sex": "女",
"age": 32
}
]
};
//注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架
//$("#table-template").html()是jquery的语法。。。
var myTemplate = Handlebars.compile($("#table-template").html());
//将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。
$('#tableList').html(myTemplate(data));
});
</script>
循环是Handlebars.js一个重要特性,#each可以理解成循环命令,循环的是json对象中的student属性。对于每次循环,都可以读出里边的name、sex、age属性。
(2)、each-循环中使用this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handlebars模板运用</title>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>each-循环中使用this</h1>
<!--基础html框架-->
<table>
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody id="tableList">
</tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">
{{#each this}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{/each}}
</script>
<!--进行数据处理、html构造-->
<script type="text/javascript">
$(document).ready(function() {
//模拟的json对象
var data = [
{
"name": "张一",
"sex": "男",
"age": 28
},
{
"name": "张二",
"sex": "女",
"age": 30
},
{
"name": "张三",
"sex": "女",
"age": 32
}
];
//注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架
//$("#table-template").html()是jquery的语法。。。
var myTemplate = Handlebars.compile($("#table-template").html());
//将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。
$('#tableList').html(myTemplate(data));
});
</script>
用#each this,表示遍历当前对象!this表示当前的上下文。
(3)、with-进入到某个属性(进入到某个上下文环境)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handlebars模板运用</title>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>with-进入到某个属性(进入到某个上下文环境)</h1>
<!--基础html框架-->
<table>
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>兴趣爱好</th>
</tr>
</thead>
<tbody id="tableList">
</tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">
{{#each this}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
<td>
{{#with favorite}}
{{#each this}}
<p>{{name}}</p>
{{/each}}
{{/with}}
</td>
</tr>
{{/each}}
</script>
<!--进行数据处理、html构造-->
<script type="text/javascript">
$(document).ready(function() {
//模拟的json对象
var data = [
{
"name": "张三丰",
"sex": "男",
"age": 28,
"favorite":
[
{
"name":"唱歌"
},{
"name":"篮球"
}
]
},
{
"name": "李妮妮",
"sex": "女",
"age": 30,
"favorite":
[
{
"name":"上网"
},
{
"name":"足球"
}
]
},
{
"name": "王妞妞",
"sex": "女",
"age": 18,
"favorite":
[
{
"name":"电影"
}, {
"name": "旅游"
}
]
}
];
//注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架
//$("#table-template").html()是jquery的语法。。。
var myTemplate = Handlebars.compile($("#table-template").html());
//将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。
$('#tableList').html(myTemplate(data));
});
</script>
在循环每名学生时,学生的favorite属性并不是一个普通的字符串,而又是一个json对象,确切的说是一个数组,我们需要把学生的爱好全部取出来。
这时候就需要with命令,这个命令可以让当前的上下文进入到一个属性中,{{#with favorite}}表示进入到favorite属性的上下文中,而favorite属性中又是一个list,因此可以用{{#each this}}进行遍历,表示遍历当前上下文环境,对于每次遍历。
(4)、if-判断的基本用法+Helper方法
在遍历student
时,由于数据缺失,并不是每一个学生都有name
属性,我们不想显示没有name
属性的学生,这时就需要if来做判断。
{{#if name}}
可以用来判断当前上下文中有没有name
属性,实际上,它是尝试去读取name
属性,如果返回的为undefined、null、""、[]、false
任意一个,都会导致最终结果为假。
其实,在Handlebars
的模板标签中,{{#if condition}}{{/if}}
只能判断这个condition
是否为true
和false
,并不能判断是否等于某个特定的值。
可以借助Handlebars
的registerHelper
方法来实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Handlebars模板运用</title>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="handlebars-v4.0.11.js"></script>
</head>
<body>
<h1>if-判断的基本用法+Helper方法</h1>
<!--基础html框架-->
<table>
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
</thead>
<tbody id="tableList"></tbody>
</table>
</body>
</html>
<!--Handlebars.js模版-->
<!--Handlebars.js模版放在script标签中,保留了html原有层次结构,模版中要写一些操作语句-->
<!--id可以用来唯一确定一个模版,type是模版固定的写法-->
<script id="table-template" type="text/x-handlebars-template">
{{#each student}}
{{#if name}}
{{#compare age 20}}
<tr>
<td>{{name}}</td>
<td>{{sex}}</td>
<td>{{age}}</td>
</tr>
{{else}}
<tr>
<td>?</td>
<td>?</td>
<td>?</td>
</tr>
{{/compare}}
{{/if}}
{{/each}}
</script>
<!--进行数据处理、html构造-->
<script type="text/javascript">
$(document).ready(function() {
//模拟的json对象
var data = {
"student": [
{
"sex": "男",
"age": 18
},
{
"name": "李四",
"sex": "女",
"age": 30
},
{
"name": "妞妞",
"sex": "女",
"age": 32
}
]
};
//注册一个Handlebars模版,通过id找到某一个模版,获取模版的html框架
//$("#table-template").html()是jquery的语法。。。
var myTemplate = Handlebars.compile($("#table-template").html());
//将json对象用刚刚注册的Handlebars模版封装,得到最终的html,插入到基础table中。
//注册一个比较大小的Helper,判断v1是否大于v2
Handlebars.registerHelper("compare",function(v1,v2,options){
if(v1>v2){
//满足添加继续执行
return options.fn(this);
}else{
//不满足条件执行{{else}}部分
return options.inverse(this);
}
});
$('#tableList').html(myTemplate(data));
});
</script>
注:Handlebars.registerHelper
用来定义Helper
,它有两个参数,第一个参数是Helper
名称,第二个参数是一个回调函数,用来执行核心业务逻辑。本例中的函数,有三个参数,其中前两个参数是需要比较的两个数,第三个参数是固定的,就叫options
,如果加了该参数,就说明这个Helper
是一个Block
,块级别的Helper
,有一定的语法结构,调用的时候加#号,就像if那样。
关于options
的使用,return options.fn(this);
表示满足条件继续执行,也就是执行{{#compare }}
和{{else}}
之间的代码;return options.inverse(this);
表示不满足条件,也就是执行{{else}}
和{{/compare}}
之间的代码。