handlebars入门
关于模板
关于为什么要使用模板引擎, 就我现在的项目而言,我还停留在进行发送Ajax请求到后台后,利用模板引擎拼接接受到的JSON字符串,展现到页面的地步
模板最本质的作用是【变静为动】一切利用这方面的都是优势,不利于的都是劣势。要很好地实现【变静为动】的目的,有这么几点:
1. 可维护性(后期改起来方便);
2. 可扩展性(想要增加功能,增加需求方便);
3.开发效率提高(程序逻辑组织更好,调试方便);
4.看起来舒服(不容易写错);
从以上四点,你仔细想想,前端模板是不是无论从哪方便优势体现都不是一点两点。其实最重要的一点就是:【视图(包括展示渲染逻辑)与程序逻辑的分离】分离的好处太多了,更好改了,更好加东西了,调试也方便了,看起来也舒服了,应用优秀的开发模式更方便了(mvvc,mvc等).
Handlebars 是 JavaScript 一个语义模板库,通过对view和data的分离来快速构建Web模板。它采用"Logic-less template"(无逻辑模版)的思路,在加载时被预编译,而不是到了客户端执行到代码时再去编译, 这样可以保证模板加载和运行的速度。Handlebars兼容Mustache,你可以在Handlebars中导入Mustache模板。
目前handlebars.js已经被许多项目广泛使用了,handlebars是一个纯JS库,因此你可以像使用其他JS脚本一样用script标签来包含handlebars.js
Handlebars基本用法
1.引入handlebars
handlebars是一个纯JS库,因此你可以像使用其他JS脚本一样用script标签来包含handlebars.js
<script type="text/javascript" src="statics/js/handlebars-v4.0.12.js"></script>
Maven配置:handlebars和handlebars-springmvc。
<dependency> <groupId>com.github.jknack</groupId> <artifactId>handlebars</artifactId> <version>4.0.5</version> </dependency> <dependency> <groupId>com.github.jknack</groupId> <artifactId>handlebars-springmvc</artifactId> <version>4.0.5</version> </dependency>
2.使用四步骤
创建模板
步骤一: 通过一个<script>将需要的模板包裹起来
步骤二: 在<script>标签中填入type和id
type类型可以是除text/javascript以外的任何MIME类型,但推荐使用type="text/template",更加语义化
id是在后面进行编译的时候所使用,让其编译的代码找到该模板.
步骤三: 在<script>标签中插入我们需要的html代码,根据后台给我们的接口文档,修改其需要动态获取的内容
<script type="text/template" id="myTemplate">
<div class="demo"> <h1>{{name}}</h1> <p>{{content}}</p> </div>
</script>
var tpl = $("#myTemplate").html(); //用jQuery获取模板
var template = Handlebars.compile(tpl);//预编译模板
var html = template(data); //匹配(数据)json内容
$('#box').html(html);//输入模板
以上述代码为例进行解释:
步骤一: 获取模板的内容放入到tpl中,这里$("#myTemplate")中填入的内容为你在上一步创建模板中所用的id.
提醒: 这里我使用的jQuery的选择器获取,当然,你可以使用原生javascript的DOM选择器获取,例如:docuemnt.getElementById('myTemplate')和document.querySelector('#myTemplate')
步骤二: 使用Handlebars.compile()方法进行预编译,该方法传入的参数即为获取到的模板
步骤三: 使用template()方法进行编译后得到拼接好的字符串,该方法传入的参数即为上一步预编译的模板.
步骤四: 将编译好的字符串插入到你所希望插入到的html文档中的位置,这里使用的是jQuery给我们提供的html()方法.同样,你也可以使用原生的innerHTML
3.语法
1)handlebars 表达式(expression)和编码
handlebars 表达式以 "{{" 开头,中间写一些内容,以" }}" 结尾
HTML编码
在handlebars里,{{expression}} 会返回一个经过编码的HTML,如果你不希望被编码,可以使用 {{{expression}}} 如:
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{{body}}} </div> </div>
handlebars 不会编码 Handlebars.SafeString。如果你自定义一个 helper,返回一段 HTML 代码,你需要返回 new Handlebars.SafeString(result)
Handlebars.registerHelper('link', function(text, url) { text = Handlebars.Utils.escapeExpression(text); url = Handlebars.Utils.escapeExpression(url); var result = '<a href=" ' + url + ' ">' + text + '</a>'; return new Handlebars.SafeString(result); });
这里将会对传入的参数进行编码,返回值是“安全的”,所以就算你不使用 {{{,handlebars 也不会再次编码了
2)块(Block)表达式
块表达式允许你定义 helper,以"{{#block context}}"开始以"{{/block}}"结束.用不同的数据上下文(context)调用一段模板
下面我们定义一个生成列表的 helper(助手):
{{#list people}}{{firstName}} {{lastName}}{{/list}}
如果我们的数据是这样的:
{ people: [ {firstName: "Yehuda", lastName: "Katz"}, {firstName: "Carl", lastName: "Lerche"}, {firstName: "Alan", lastName: "Johnson"} ] }
我们创建一个叫 list (这是一个自定义块级表达式)的 helper 来生成列表,helper 接受 people 作为第一个参数,一个 options对象(hash)作为第二个参数.options 包含一个属性 fn,他可以调用一个 context 就像普通模板一样.
Handlebars.registerHelper('list', function(items, options) { var out = "<ul>"; for(var i=0, l=items.length; i<l; i++) { out = out + "<li>" + options.fn(items[i]) + "</li>"; } return out + "</ul>"; });
执行后,得到:
<ul> <li>Yehuda Katz</li> <li>Carl Lerche</li> <li>Alan Johnson</li> </ul>
块表达式有很多特性,例如,可以创建一个 else 块(内置的 if helper 就有 else 块)。另外,如果 options.fn(context) 对内容编码过了,handlebars 就不会 helper 内容进行编码了
3)常用内置块级表达式
Handlebars内置了with,each,if,unless,log这5种基本的Helpers。
if helper只能判断true或false,不能执行一些复杂的运算逻辑.如:{{#if value1==value2}}
如果参数返回false、undefined、null、""或者[](一个返回false的值),Handlebars将不会呈现代码块,此时可以自定义if
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '===':
return (v1 === v2) ? options.fn(this) : options.inverse(this);
case '<':
return (v1 < v2) ? options.fn(this) : options.inverse(this);
}
});
在像这样的模板中使用它: {{#ifCond var1 '==' var2}}
unless helper
你可以使用unless helper作为与if helper互逆的操作.Unless语句会在表达式返回false时输出代码块。
each helper
可以通过内置each helper迭代一个列表。在代码块内部,可以使用this引用当前正迭代的元素。
<ul class="people_list"> {{#each people}} <li>{{this}}</li> {{/each}} </ul>
当使用上下文:
{ people: [ "Yehuda Katz", "Alan Johnson", "Charles Jolley" ] }
将会输出:
<ul class="people_list"> <li>Yehuda Katz</li> <li>Alan Johnson</li> <li>Charles Jolley</li> </ul>
你可以使用this表达式在任何上下文中以引用当前的上下文元素。
{{else}}片段可以有选择的提供,仅当列表为空的时候,它才会被显示。
{{#each paragraphs}} <p>{{this}}</p> {{else}} <p class="empty">No content</p> {{/each}}
当通过each遍历元素项时,你可以使用{{@index}}引用当前正遍历元素的索引。
{{#each array}} {{@index}}: {{this}} {{/each}}
注册索引加一的helper
var handleHelper = Handlebars.registerHelper("addOne",function(index){ return parseInt(index)+1; });
<script id="table-template" type="text/x-handlebars-template"> {{#each this}} <tr> <td>{{addOne @index}}.</td> <td>{{name}}</td> <td>{{sex}}</td> <td>{{age}}</td> </tr> {{/each}} </script>
此外,为了遍历对象,{{@key}}可用于引用当前的键名:
{{#each object}} {{@key}}: {{this}} {{/each}}
遍历数组时,第一和最后一步采用@first 和 @last变量标记。当遍历一个对象时,只能使用@first。
4)上下文
"../" 引用上一级上下文.如: <p>{{../name}} or {{this/name}} or {{this.name}}</p>
模板注释 {{! }} or {{!-- --}}
使用 this 可以访问到当前的上下文
<ul id="test">
<script type="text/template" id="agree">
{{#each items}}
<li>{{agree_button}}</li>
{{/each}}
</script>
</ul>
<script type="text/javascript">
var context = {
items: [
{name: "Handlebars", emotion: "love"},
{name: "Mustache", emotion: "enjoy"},
{name: "Ember", emotion: "want to learn"}
]
};
Handlebars.registerHelper('agree_button', function() {
return new Handlebars.SafeString(
"<button>I agree. I " + this.emotion + " " + this.name + "</button>"
);
});
var getTemplate=$("#agree").html();
var compileTemp=Handlebars.compile(getTemplate);
var html=compileTemp(context);
$("#test").html(html);
</script>
结果:
<ul id="test">
<li><button>I agree. I love Handlebars</button></li>
<li><button>I agree. I enjoy Mustache</button></li>
<li><button>I agree. I want to learn Ember</button></li>
</ul>
5)注册helper
Handlebars.registerHelper(name, helper)
Handlebars.registerHelper('foo', function() { });
同样支持一次注册多个helpers:
Handlebars.registerHelper({ "foo": function() { }, "bar": function() { } });
Handlebars.unregisterHelper(name)
注销一个之前注册的helper:
Handlebars.unregisterHelper('foo');

浙公网安备 33010602011771号