您的位置:首页 > 其它

Handlebars模板开发指南

2015-08-31 14:29 465 查看


基础语法

Handlebars模板看起来和一般的HTML没什么两样,只不过是在HTML中嵌入了Handlebars的表达式。如下:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>


一个Handlebars的表达式是被
{{
}}
包含起来的内容。了解更多Handlebars表达式

你可以将模板的内容或数据放到一个<script>标签里,也可以直接写在javascript里:
<script id="entry-template" type="text/x-handlebars-template">
template content
</script>


当你写了一个模板以后,使用
Handlebars.compile
方法将模板编译为函数,生成的执行函数接受context作为参数,用来渲染模板。了解更多执行函数

比如下面:
var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
"{{kids.length}} kids:</p>" +
"<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
var template = Handlebars.compile(source);

var data = { "name": "Alan", "hometown": "Somewhere, TX",
"kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
var result = template(data);

// 将被渲染为:
// <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
// <ul>
//   <li>Jimmy is 12</li>
//   <li>Sally is 4</li>
// </ul>


你还可以预编译你的模板,它将会生成一个小一些的运行库,这对移动设备上的web页面非常重要。了解更多预编译


HTML转义

为安全起见,Handlebars表达式中的一些HTML字符将被转义,如果你不想让Handlebars转义字符,使用三个花括号
{{{

//template:

<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{{body}}}
</div>
</div>

//context:

{
title: "All about <p> Tags",
body: "<p>This is a post about <p> tags</p>"
}

//results:

<div class="entry">
<h1>All About <p> Tags</h1>
<div class="body">
<p>This is a post about <p> tags</p>
</div>
</div>


Handlebars不会转义Handlebars.SafeString,如果你想写一个输出自身HTML的helper,你可以使用这个方法,用来手动的输出需要转义的参数。
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);
});


块级表达式

块级表达式能让你定义块级helpers,它能调用模板的一部分,并且使用与当前不同的上下文。下面以一个输出HTML列表的helper为例:
{{#list people}}{{firstName}} {{lastName}}{{/list}}


定义如下的上下文:
{
people: [
{firstName: "Yehuda", lastName: "Katz"},
{firstName: "Carl", lastName: "Lerche"},
{firstName: "Alan", lastName: "Johnson"}
]
}


我们可以创建一个名为list的helper来生成HTML列表,这个helper接受people和options参数,options包含fn属性,可以调用上下文。
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>


块级helper包含更多的特性,如创建一个
else
部分(在内建的
if
helper里有用到)。

当调用
options.fn(context)
时内部的内容已经被转义,因此Handlebars不会转义块级helper的结果,否则会出现两次转义。了解更多块级helper


Handlebars路径

和Mustache一样,Handlebars支持简单的路径。

Handlebars还支持嵌套的路径,可以在当前上下文中寻找嵌套的属性。
<div class="entry">
<h1>{{title}}</h1>
<h2>By {{author.name}}</h2>

<div class="body">
{{body}}
</div>
</div>


其对应的上下文如下:
var context = {
title: "My First Blog Post!",
author: {
id: 47,
name: "Yehuda Katz"
},
body: "My first post. Wheeeee!"
};


因此Handlebars模板能支持更多原始的JSON对象。

嵌套的handlebars路径可以包含
../
字符段,可以将路径定位到父级上下文中。
<h1>Comments</h1>

<div id="comments">
{{#each comments}}
<h2><a href="/posts/{{../permalink}}#{{id}}">{{title}}</a></h2>
<div>{{body}}</div>
{{/each}}
</div>


在这个例子中,post是comments的父级上下文,虽然a标签处于comments的上下文里,但permalink可以上溯到post上下文中。

更严密的讲,
../
路径指的是父级模板的作用域,而不是高一级的上下文,这是因为块级helper能调用任何上下文,所以“上一级”的概念在这里并不适合。


模板注释

在handlebars中使用
{{! }}
或者
{{!-- --}}
来包含注释。
<div class="entry">
{{! only output this author names if an author exists }}
{{#if author}}
<h1>{{firstName}} {{lastName}}</h1>
{{/if}}
</div>


Helpers(辅助方法)

Helpers是Handlebars中最重要的概念,它能大大扩展Handlebars的使用范围,Helper自定义函数的形式将所需要的功能注册为表达式,然后可以在Handlebars中使用。

Handlebars提供了
Handlebars.registerHelper
方法来自定义Helper,同时也提供了一些常用的内建Helper。

比如有如下模板:
<div class="post">
<h1>By {{fullName author}}</h1>
<div class="body">{{body}}</div>

<h1>Comments</h1>

{{#each comments}}
<h2>By {{fullName author}}</h2>
<div class="body">{{body}}</div>
{{/each}}
</div>


其中上下文和helper如下:
var context = {
author: {firstName: "Alan", lastName: "Johnson"},
body: "I Love Handlebars",
comments: [{
author: {firstName: "Yehuda", lastName: "Katz"},
body: "Me too!"
}]
};

Handlebars.registerHelper('fullName', function(person) {
return person.firstName + " " + person.lastName;
});


运行结果:
<div class="post">
<h1>By Alan Johnson</h1>
<div class="body">I Love Handlebars</div>

<h1>Comments</h1>

<h2>By Yehuda Katz</h2>
<div class="body">Me Too!</div>
</div>


Helpers还可以接受块级元素当前的上下文,就像函数中的this上下文一样。
<ul>
{{#each items}}
<li>{{agree_button}}</li>
{{/each}}
</ul>


上下文及helper如下:
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>"
);
});


运行结果:
<ul>
<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>


内建Helpers

Handlebars提供了一系列的内建Helper供直接调用。

with:切换上下文

each:循环输出上下文中的内容,用this表达式指代单条内容,else表达式当上下文为空时激活

if:条件表达式

unless:与if表达式功能相反

log:输出log
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: