Handlebars学习之——块表达式

本文详细介绍了Handlebars中的块表达式,包括基本块、with helper、简单迭代器、条件表达式、hash参数、块参数和raw helper的使用方法。重点讲解了如何自定义迭代器和条件表达式,以及如何利用hash参数和块参数来改变上下文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Block helper可以让你自定义迭代器和其他可以传入新的上下文的功能

基本块

Block helper的定义方法是:在一个mustache中,以#开头,后面跟着helper的名称,然后对应的在一个mustache中以/开头,加上相同的名称作为这个块的结尾。

形如:

{{#hello}}
  {{item}}
{{/hello}}

在helper中,function接收一个hash参数options,而options有个fn方法,该方法可接收一个context参数来改变block中的上下文,返回一个类似于编译后的Handlebars模板,明确地说,就是一个字符串。

Handlebars.registerHelper('hello', function(options){
  return options.fn(this);
});

在上面的代码中,我们给options.fn传入了一个新的上下文,这个新的context是this,就是代表当前的上下文,因此,如果当前的上下文是:

{
  title: 'This is the title.',
  body: 'body',
  item: 'item'
}

那么block中的item标识符最终返回字符串'item'

注:以这种方式定义的helper,在模板中,可以使用path,如上面的{{item}}可以写成{{./item}}

with helper(内置)

with helper会把传入的context直接调用,实现如下

Handlebars.registerHelper('with', function(context, options) {
  return options.fn(context);
});

当处理json的时候用with比较方便

<div class="entry">
  <h1>{{title}}</h1>
  {{#with story}}
    <div class="intro">{{{intro}}}</div>
    <div class="body">{{{body}}}</div>
  {{/with}}
</div>

context:

{
  title: "First Post",
  story: {
    intro: "Before the jump",
    body: "After the jump"
  }
}

简单迭代器

先来看一下内置的each helper是怎么实现的

<div class="comments">
  {{#each comments}}
    <div class="comment">
      <h2>{{subject}}</h2>
      {{{body}}}
    </div>
  {{/each}}
</div>

helper:

Handlebars.registerHelper('each', function(context, options) {
  var ret = "";

  for(var i=0, j=context.length; i<j; i++) {
    ret = ret + options.fn(context[i]);
  }

  return ret;
});

其实就是在helper中遍历了一次context。明白了这一点,我们就可以对其进行改造,实现自定义的迭代器了。如:

{{#list nav}}
  <a href="{{url}}">{{title}}</a>
{{/list}}

context:

{
  nav: [
    { url: "http://www.yehudakatz.com", title: "Katz Got Your Tongue" },
    { url: "http://www.sproutcore.com/block", title: "SproutCore Blog" },
  ]
}

helper:

Handlebars.registerHelper('list', function(context, options) {
  var ret = "<ul>";

  for(var i=0, j=context.length; i<j; i++) {
    ret = ret + "<li>" + options.fn(context[i]) + "</li>";
  }

  return ret + "</ul>";
});

条件表达式

Handlebars中内置的if只能判断true/false,具体实现如下:

{{#if isActive}}
  <img src="star.gif" alt="Active">
{{else}}
  <img src="cry.gif" alt="Inactive">
{{/if}}

helper:

Handlebars.registerHelper('if', function(conditional, options) {
  if(conditional) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

其中,options.inverse用来处理block中的else语句,对此,我们也可以实现自定义的条件helper来增强条件语句的功能

Handlebars.registerHelper('equal' function(param1, param2, options) {
  if(param1 == param2) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});
{{#equal 'hello' 'world'}}
  <p>==</p>
  {{else}}
  <p>!=</p>
{{/equal}}

以上示例展示了判断两个变量相等或不等时执行的操作。

此外,Handlebars支持链式的条件语句,如

{{#if isActive}}
  <img src="star.gif" alt="Active">
{{else if isInactive}}
  <img src="cry.gif" alt="Inactive">
{{/if}}

hash参数

hash arguments在之前的文章有提到过,就是将一些键值对序列作为helper回调函数最后一个参数的值,通过options.hash来访问。

{{#list nav id="nav-bar" class="top"}}
  <a href="{{url}}">{{title}}</a>
{{/list}}
Handlebars.registerHelper('list' function(context, options) {
  var attrs = Em.keys(options.hash).map(function(key) {
    return key + '="' + options.hash[key] + '"';
  }).join(" ");

  return "<ul " + attrs + ">" + context.map(function(item) {
    return "<li>" + options.fn(item) + "</li>";
  }).join("\n") + "</ul>";
});

块参数

Handlebars 3.0的新特性。

{{#each users as |user userId|}}
  Id: {{userId}} Name: {{user.name}}
{{/each}}

这边user会取当前context的值,而userId会取当前遍历context的索引值。
有点类似于JavaScript里的Array.map

raw helper

之前也提到过,用来转义的

{{{{raw-helper}}}}
  {{bar}}
{{{{/raw-helper}}}}

helper:

Handlebars.registerHelper('raw-helper', function(options) {
  return options.fn();
});

输出:

{{bar}}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值