Handlebars自定义Helper
关于Handlebars模板的使用,官网给出的文档实在有点凌乱,好在上手容易,看看官方的文档就能入门了。但是对于helper的自定义,官网没有做详细的介绍,后来发现一篇比较好的英文教程,真正可以说从入门到精通,详细介绍了handlebars的使用,有兴趣的可以点这里,这里只翻译其中关于自定义Helper的章节。
———————————————–分割线——————————————————-
Handlebars.js自定义Helpers
除了前面讨论的内建的helper,Handlebars允许我们添加自定义的helper,相对于内建的helper,这更为重要,因为我们可以在自定义的helper中添加复杂的逻辑。如果你愿意,你甚至可以用我们自定义的helper重新定义内建的helper,但我觉得你不至于这么闲的蛋疼。
在自定义的helper中,我们可以添加任何的JS逻辑。我们需要在所有Handlebars JS代码之前注册helper。自定义的helper在JS代码中创建,而非Handlebars的模板中。
创建helper有两种方式:块级helper与非块级helper。
一、自定义函数helper
因为内建的helper中没有条件判断的逻辑,所以我就以条件逻辑判断为例,做一个简单的自定义函数helper。
数据对象为:
var contextObj = {score:85, userName:"Mike"};
首先,使用Handlebars.registerHelper方法注册自定义的helper。这个方法接收两个参数,第一个为字符串类型,用作helper的名字,第二个参数为一个函数,接收任意个数的参数。示例代码如下:
Handlebars.registerHelper ("theNameOfTheHelper", function (theScore) { console.log("Grade: " + theScore ); var userGrade = "C"; if (theScore >= 90) { return "A" ; } else if (theScore >= 80 && theScore < 90) { return "B" ; } else if (theScore >= 70 && theScore < 80) { return "C" ; } else { return "D" ; } });
你可以这样使用我们刚创建的自定义函数helper:
<script id="shoe-template" type="x-handlebars-template"> {{theNameOfTheHelper score}} </script>
HTML页面输出结果为:
B
自定义块级helper
除了自定义函数helper,我们还可以添加自定义块级helper。当我们注册一个自定义块级helper时,Handlebars会自动给回调函数添加一个options对象,最为回调函数的最后一个参数。这个options对象有一个fn方法,一个hash对象和一个inverse方法。
options.fn方法:
fn方法接收一个对象(你的数据)作为参数,在自定义块级helper的模板中作为上下文使用。在模板中,你可以传递任何数据对象,如果你想使用与外层模板相同的上下文,你可以简单的传递一个this。
下面通过一个简单的例子来方便理解。下面就是我们要使用的数据对象(我们会将数组中每个对象的score数组求和,并用这个值替换score数组):
var contextObj = [{firstName: "Kapil", lastName:"Manish", score:[22, 34, 45, 67]}, {firstName: "Bruce", lastName:"Kasparov", score:[10, 34, 67, 90]}];
下面是我们用userScore这个块级helper写一个模板,关于userScore块级helper,我们将稍后定义:
<script id="shoe-template" type="x-handlebars-template"> {{#userScore this}} <div>{{firstName}} {{lastName}}, Your Total Score is {{score}} </div> {{/userScore}} </script>
下面我们来使用Handlebars.registerHelper方法注册userScore块级helper。注意Handlebars会自动的将options对象添加到回调函数中,所以我们可以在这里直接使用:
Handlebars.registerHelper ("userScore", function (dataObject, options) { var templateWithInterpolatedData = ""; for (var i = dataObject.length - 1; i >= 0; i--) { //求出score数组的和,并用这个值替换掉score数组 dataObject[i].score = dataObject[i].score.reduce(function (prev, cur, index, array) { return prev + cur; }); // dataObject的每个数组元素都会通过options.fn方法处理,options.fn方法会将数组元素的值插入到模板中对应的位置,并将生成的HTML返回 // 希望下面的解释可以帮助你理解options.fn方法: options.fn方法就和常规的handlebars模板函数一样,拿到我们的数据对象,将这些值插入到模板中对应的位置,然后返回生成的HTML // 本例中如果没有调用options.fn方法, 那么未经处理的数据将被原样返回 templateWithInterpolatedData += options.fn (dataObject[i]); } // 最后,我们将用dataObject值填充后的完整的HTML字符串返回 return templateWithInterpolatedData; });
输出结果为:
Bruce Kasparov, Your Total Score is 201
Kapil Manish, Your Total Score is 168
同样重要的是,一个自定义的块级helper可以在模板中的任意地方插入,并且我们可以在模板中给helper传递任意个数的参数。
下面来介绍一下options.inverse方法:
如果你用过if/else这个内建helper,你应该可以理解,其实inverse方法和fn方法正相反,它是用在块级语句的else部分的。当回调函数中的表达式符合你的逻辑真值时,你可以使用options.fn;相反的,如果表达式符合你的逻辑假值时,你可以使用options.inverse方法来解析模板中else部分的内容。
最后来说下options.hash对象:
Handlebars表达式不仅能接收字符串和变量作为参数,还能接收通过空格分隔的键值对作为参数。举例来说(注意键值对参数之间没有逗号):
{{#myNewHelper score=30 firstName="Jhonny" lastName="Marco"}} Show your HTML content here. {{/myNewHelper}}
上面的Handlebars表达式中的键值对将会被自动添加到helper回调函数的hash对象中。我们可以做个验证:
Handlebars.registerHelper ("myNewHelper", function (dataObject, options) { // JSON.stringify 用于将dataObject对象序列化成一个数组 console.log(JSON.stringify (options.hash)); // 输出结果: {score:30, firstName:"Jhonny", lastName:"Marco"} });
———————————————–分割线——————————————————-
简单介绍下另一个话题:Partials(子模板)
有时候你需要在一个大模板中套用另一个模板,这时候你可以使用Partials,下面是partials的使用语法:
{{> partialName}}
在使用partial之前同样需要注册partial:
Handlebars.registerPartial(“partialName”,你的partial的html);
partial的html和模板的html定义方法相同,在此不再赘述。一个重要的提示:partial和外部的模板享用同样的上下文。
Click here for more information
UR Brother - 2013 年 11 月 15 日 10:23 上午
哇嘎里麻善嗯!
keenwon - 2014 年 4 月 3 日 3:33 下午
for (var i = dataObject.length – 1; i >= 0; i–) {….}
凌乱了
lovecicy - 2014 年 4 月 3 日 6:14 下午
反着循环而已啊