handlebars使⽤教程
Handlebars 为你提供了⼀个可以毫⽆挫折感的⾼效率书写 语义化的模板 所必需的⼀切。
Mustache 模板和 Handlebars 是兼容的,所以你可以把Mustache模板拿来导⼊到Handlebars中,并开始使⽤Handlebars所提供的更丰富的功能。
开始
Handlebars模板看起来就像是正常的Html,并使⽤了嵌⼊的 handlebars 表达式。
<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div></div>
在 JavaScript 中使⽤ pile
来编译模板。
var source = $("#entry-template").html();var template = pile(source);
得到下⾯的HTML
<div class="entry"> <h1>My New Post</h1> <div class="body"> This is my first post! </div></div>
使⽤这段上下⽂(数据):
{ title: "All about <p> Tags", body: "<p>This is a post about <p> tags</p>"}
会得到如下结果:
<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
安全字符串进⾏编码。如果你写的 helper ⽤来⽣成 HTML,就经常需要返回⼀个 new Handlebars.SafeString(result)
。在这种情况下,你就需要⼿动的来编码参数了。
Handlebars.Utils.escapeExpression(url); var result = '<a href="' + url + '">' + text + '</a>'; return new
Handlebars.SafeString(result);});
这样来编码传递进来的参数,并把返回的值标记为 安全,这样的话,即便不是哟给你“三个⼤括号”,Handlebars 就不会再次编码它了。
块级表达式
块级表达式允许你定义⼀个helpers,并使⽤⼀个不同于当前的上下⽂(context)来调⽤你模板的⼀部分。现在考虑下这种情况,你需要⼀个helper来⽣成⼀段 HTML 列表:
{{#list people}}{{firstName}} {{lastName}}{{/list}}
并使⽤下⾯的上下⽂(数据):
{ people: [ {firstName: "Yehuda", lastName: "Katz"}, {firstName: "Carl", lastName: "Lerche"}, {firstName: "Alan", lastName: "Johnson"} ]}
蜂的作者是谁
此时需要创建⼀个 名为 list
的 helper 来⽣成这段 HTML 列表。这个 helper 使⽤ people
作为第⼀个参数,还有⼀个options
对象(hash哈希)作为第⼆个参数。这个 options 对象有⼀个叫 fn
的属性,你可以传递⼀个上下⽂给它(fn),就跟执⾏⼀个普通的 Handlebars 模板⼀样:
执⾏之后,这个模板就会渲染出:
<ul> <li>Yehuda Katz</li> <li>Carl Lerche</li> <li>Alan Johnson</li></ul>
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>
../豆腐汤
标识符表⽰对模板的⽗级作⽤域的引⽤,并不表⽰在上下⽂数据中的上⼀层。这是因为块级 helpers 可以以任何上下⽂来调⽤⼀个块级表达式,所以这个【上⼀层】的概念⽤来指模板作⽤域的⽗级更有意义些。
Handlebars也允许通过⼀个 this
的引⽤来解决 helpers 和 数据字段间的名字冲突:
<p>{{./name}} or {{this/name}} or {{this.name}}</p>
上⾯的这⼀种⽅式都会将 name
字段引⽤到当前上下⽂上,⽽不是 helper 上的同名属性。
模板注释:{{! }} 或 {{!-- --}}
毓婷避孕药副作用你可以在 handlebars 代码中加注释,就跟在代码中写注释⼀样。对于有⼀定程度的逻辑的部分来说,这倒是⼀个很好的实践。
<div class="entry"> {{! only output this author names if an author exists }} {{#if author}} <h1>{{firstName}} {{lastName}}</h1> {{/if}}</div>
注释是不会最终输出到返回结果中的。如果你希望把注释展⽰出来,就使⽤ HTML 的注释就⾏了。
<div class="entry"> {{! This comment will not be in the output }} </div>
所有注释都必须有 }}
江城子密州出猎苏轼
,⼀些多⾏注释可以使⽤ {{!-- --}}
语法。
Helpers
Handlebars 的 helpers 在模板中可以访问任何的上下⽂。可以通过 isterHelper
⽅法注册⼀个 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>
当时⽤下⾯的上下⽂数据和 helpers:
var context = { author: {firstName: "Alan", lastName: "Johnson"}, body: "I Love Handlebars", comments: [{ author: {firstName: "Yehuda", lastName: "Katz"}, body: "Me too!" }]};isterHelper('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>
当使⽤下⾯的 this上下⽂ 和 helpers:
var context = { items: [ {name: "Handlebars", emotion: "love"}, {name: "Mustache", emotion: "enjoy"}, {name: "Ember", emotion: "want to learn"} ]};isterHelper('agree_button', function() { return new Handlebars.SafeString( "<button>I agree. I " + ion + " " + 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>
如果你不希望你的 helper 返回的 HTML 值被编码,就请务必返回⼀个 new Handlebars.SafeString
内置的 Helpers
with
helper
⼀般情况下,Handlebars 模板在计算值时,会把传递给模板的参数作为上下⽂。
var source = "<p>{{lastName}}, {{firstName}}</p>";var template = pile(source);template({firstName: "Alan", lastName: "Johnson"});
结果如下:
<p>Johnson, Alan</p>
不过也可以在模板的某个区域切换上下⽂,使⽤内置的 with
helper即可。
<div class="entry"> <h1>{{title}}</h1> {{#with author}} <h2>By {{firstName}} {{lastName}}</h2> {{/with}}</div>
在使⽤下⾯数据作为上下⽂时:
{ title: "My first post!", author: { firstName: "Charles", lastName: "Jolley" }}
会得到如下结果:
<div class="entry"> <h1>My first post!</h1> <h2>By Charles Jolley</h2></div>
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
表达式在任何上下⽂中表⽰对当前的上下⽂的引⽤。
还可以选择性的使⽤ el
,当被循环的是⼀个空列表的时候会显⽰其中的内容。
{{#each paragraphs}} <p>{{this}}</p>{{el}} <p class="empty">No content</p>{{/each}}
在使⽤ each
来循环列表的时候,可以使⽤ {{@index}}
来表⽰当前循环的索引值。
{{#each array}} {{@index}}: {{this}}{{/each}}
对于 object 类型的循环,可以使⽤ {{@key}}
来表⽰:
{{#each object}} {{@key}}: {{this}}{{/each}}
if
helper
if
表达式可以选择性的渲染⼀些区块。如果它的参数返回 fal
, undefined
,
null
, ""
或 []
(**译注:还有 0
**)(都是JS中的“假”值),Handlebars 就不会渲染这⼀块内容:
<div class="entry"> {{#if author}} <h1>{{firstName}} {{lastName}}</h1> {{/if}}</div>
当时⽤⼀个空对象({}
)作为上下⽂时,会得到:
<div class="entry"></div>
在使⽤ if
表达式的时候,可以配合 {{el}}
来使⽤,这样当参数返回 假 值时,可以渲染 el 区块:
<div class="entry"> {{#if author}} <h1>{{firstName}} {{lastName}}</h1> {{el}} <h1>Unknown Author</h1> {{/if}}</div>
unless
输入验证码helper
红螺
unless
helper 和 if
helper 是正好相反的,当表达式返回假值时就会渲染其内容:
<div class="entry"> {{#unless licen}} <h3 class="warning">WARNING: This entry does not have a licen!</h3> {{/unless}}</div>
如果在当前上下⽂中查找 licen
返回假值,Handlebars 就会渲染这段警告信息。反之,就什么也不输出。
log
helper
log
helper 可以在执⾏模板的时候输出当前上下⽂的状态。
{{log "Look at me!"}}
>种辣椒