Handlebars是ECMAScript一个语义模板库,通过对view和data的分离来快速构建Web模板。它采用"Logic-lesstemplate"(无逻辑模版)的思路,在加载时被预编译,而不是到了客户端执行到代码时再去编译,这样可以保证模板加载和运行的速度。Handlebars兼容Mustache,你可以在Handlebars中导入Mustache模板。
使用与安装
Handlebars的安装非常简单,你只需要从GitHub下载最新版本,你也可访问下面网址获取最新信息:http://handlebarsjs.com。
目前handlebars.js已经被许多项目广泛使用了,handlebars是一个纯JS库,因此你可以像使用其他JS脚本一样用script标签来包含handlebars.js
\u003cscripttype="text/ECMAScript"src=".js/handlebars.js"\u003e\u003c/script\u003e
基本语法
Handlebarsexpressions是handlebars模板中最基本的单元,使用方法是加两个花括号{{value}},handlebars模板会自动匹配相应的数值,对象甚至是函数。
例如:\u003cdivclass="demo"\u003e\u003ch1\u003e{{name}}\u003c/h1\u003e\u003cp\u003e{{content}}\u003c/p\u003e\u003c/div\u003e
你可以单独建立一个模板,ID(或者class)和type很重要,因为你要用他们来获取模板内容例如:
\u003cscriptid="tpl"type="text/x-handlebars-template"\u003e\u003cdivclass="demo"\u003e\u003ch1\u003e{{title}}\u003c/h1\u003e\u003cp\u003e{{content.title}}\u003c/p\u003e\u003c/div\u003e\u003c/script\u003e
handlebars会根据上下文来自动对表达式进行匹配,如果匹配项是个变量,则会输出变量的值,如果匹配项是个函数,则函数会被调用。
如果没找到匹配项,则没有输出。表达式也支持点操作符,因此你可以使用{{content.title}}这样的形式来调用嵌套的值或者方法,handlebars会根据当前上下文输出content变量的title属性的值。
在ECMAScript中,使用Handlebars.compile()方法来预编译模板例如:(这是一套规则)
//用jquery获取模板
vartpl=$("#tpl")HTML();
//原生方法
varsource=document.getElementById('#tpl').innerHTML;
//预编译模板
vartemplate=Handlebars.compile(source);
//模拟json数据
varcontext={name:"zhaoshuai",content:"learnHandlebars"};
//匹配json内容
varhtml=template(context);
//输入模板
$(body)HTML(html);
表达式
Block表达式
有时候当你需要对某条表达式进行更深入的操作时,Blocks就派上用场了,在Handlebars中,你可以在表达式后面跟随一个#号来表示Blocks,然后通过{{/表达式}}来结束Blocks。如果当前的表达式是一个数组,则Handlebars会“自动展开数组”,并将Blocks的上下文设为数组中的元素。例如:
\u003cul\u003e{{#programme}}\u003cli\u003e{{language}}\u003c/li\u003e{{/programme}}\u003c/ul\u003e
有以下json数据
{programme:[{language:"ECMAScript"},{language:"HTML"},{language:"层叠样式表"}]}
编译模板代码同上……上面的代码会自动匹配programme数据并展开数据,渲染DOM后就是这样的
\u003cul\u003e\u003cli\u003eJavaScript\u003c/li\u003e\u003cli\u003eHTML\u003c/li\u003e\u003cli\u003eCSS\u003c/li\u003e\u003c/ul\u003e
内置块表达式
(Blockhelper)
1.eachblockhelper
你可以使用内置的{{#each}}helper遍历列表块内容,用this来引用遍历的元素例如:
\u003cul\u003e{{#eachname}}\u003cli\u003e{{this}}\u003c/li\u003e{{/each}}\u003c/ul\u003e
对应适用的json数据
{name:["HTML","层叠样式表","ECMAScript"]};
这里的this指的是数组里的每一项元素,和上面的Block很像,但原理是不一样的这里的name是数组,而内置的each就是为了遍历数组用的,更复杂的数据也同样适用。
2.ifelseblockhelper
{{#if}}就你使用JavaScript一样,你可以指定条件渲染DOM,如果它的参数返回false,undefined,null,""或者[](a"falsy"value),Handlebar将不会渲染DOM,如果存在{{#else}}则执行{{#else}}后面的渲染
例如:
{{#iflist}}\u003culid="list"\u003e{{#eachlist}}\u003cli\u003e{{this}}\u003c/li\u003e{{/each}}\u003c/ul\u003e{{else}}\u003cp\u003e{{error}}\u003c/p\u003e{{/if}}
对应适用json数据
vardata={info:['html5','CSS3',"WebGL"],"error":"数据取出错误"}
这里{{#if}}判断是否存在list数组,如果存在则遍历list,如果不存在输出错误信息
3.unlessblockhelper
{{#unless}}这个语法是反向的if语法也就是当判断的值为false时他会渲染DOM例如:
{{#unlessdata}}\u003culid="list"\u003e{{#eachlist}}\u003cli\u003e{{this}}\u003c/li\u003e{{/each}}\u003c/ul\u003e{{else}}\u003cp\u003e{{error}}\u003c/p\u003e{{/unless}}
4.withblockhelper
{{#with}}一般情况下,Handlebars模板会在编译的阶段的时候进行context传递和赋值。使用with的方法,我们可以将context转移到数据的一个section里面(如果你的数据包含section)。这个方法在操作复杂的template时候非常有用。
\u003cdivclass="entry"\u003e\u003ch1\u003e{{title}}\u003c/h1\u003e{{#withauthor}}\u003ch2\u003eBy{{firstName}}{{lastName}}\u003c/h2\u003e{{/with}}\u003c/div\u003e
对应适用json数据
{title:"Myfirstpost!",author:{firstName:"Charles",lastName:"Jolley"}}
Handlebar的注释(comments)
Handlebars也可以使用注释写法如下
{{!handlebarscomments}}
Handlebars的访问(Path)
Handlebar支持路径和mustache,Handlebar还支持嵌套的路径,使得能够查找嵌套低于当前上下文的属性
可以通过。来访问属性也可以使用../,来访问父级属性。例如:(使用。访问的例子)
\u003cH1\u003e{{author.id}}\u003c/h1\u003e
对应json数据
{title:"MyFirstBlogPost!",author:{id:47,name:"YehudaKatz"},body:"Myfirstpost.Wheeeee!"};
例如:(使用../访问)
{{#withperson}}\u003ch1\u003e{{../company.name}}\u003c/h1\u003e{{/with}}
对应适用json数据
{"person":{"name":"Alan"},company:{"name":"Rad,Inc."}};
自定义helper
Handlebars,可以从任何上下文可以访问在一个模板,你可以使用Handlebars.registerHelper()方法来注册一个helper。
调试技巧
把下面一段"debughelper"加载到你的ECMAScript代码里,然后在模板文件里通过{{debug}}或是{{debugsomeValue}}方便调试数据
Handlebars.registerHelper("debug",函数(optionalValue){console.log("CurrentContext");console.log("====================");console.log(this);if(optionalValue){console.log("Value");console.log("====================");console.log(optionalValue);}});
handlebars的jquery插件
(函数($){varcompiled={};$.fn.handlebars=function(template,data){if(templateinstanceofjQuery){template=$(template)HTML();}compiled[template]=Handlebars.compile(template);this.html(compiled[template](data));};})(jQuery);$('#content').handlebars($('#template'),{name:"Alan"});