如何在自定义帮助程序块中呈现 Handlebars 变量?

How can one render Handlebars variables inside a custom helper block?

我正在尝试让两个 Handlebars 变量呈现在我创建的自定义 Handlebars 助手中。

我正在为 handlebars.js 使用 Express.js 视图引擎,并且在我的 app.js 中设置了一个助手来比较相等性:

const hbs = require('hbs');

app.set('view engine', 'hbs');

hbs.registerHelper('ifEqual', (a, b, options) => {
  if (a === b) {
    return options.fn(this);
  }
  return options.inverse(this);
});

我的控制器将两个变量传递给视图:

res.render('my-view', {
  x: 3,
  y: 3,
});

my-view.hbs 中,如果变量相等,我想渲染它们,所以我尝试了:

{{#ifEqual x y}}
  foo
  {{x}}
  {{y}}
{{/ifEqual}}

结果仅 foo 呈现。为什么 {{x}}{{y}} 不在此处呈现?我需要部分执行此操作吗?

好的,所以我用不同的方法做到了:

hbs.registerHelper('renderVars', (a, b) => {
  let output;
  if (a === b) {
    output = `foo ${a} ${b}`;
  } else {
    output = 'foo';
  }
  return output;
});

那么在我看来:

{{#renderVars x y}}
{{/renderVars}}

您的模板不会在 ifEqual 块中呈现 xy 值的原因是因为没有 xy 该块上下文中的属性。上下文中缺少这些属性的原因非常简单:这是因为在您对 registerHelper 的调用中,您使用了箭头函数表达式来定义辅助函数。

Arrow Functions Expressions,除了语法更紧凑外,与标准的函数表达式不同。这种情况下的重要区别在于它们没有自己的 this 上下文。

当您调用 registerHelper 时,Handlebars 会将辅助回调函数绑定到模板的数据上下文,在本例中为对象:{ x: 3, y: 3 }。但是,这仅在您使用 常规函数表达式 作为回调并且 而不是 箭头函数表达式时有效 - 因为箭头函数表达式不能动态绑定到不同的 this 上下文。

这意味着您必须使用正则函数表达式作为 registerHelper:

的参数
hbs.registerHelper('ifEqual', function (a, b, options) {
    // Function body remains the same.
}); 

为了更好地了解哪里出了问题,您可以 console.log(this) 在您的助手中使用两种函数表达式类型并比较不同之处。

我创建了一个 fiddle 来展示差异。