如何在自定义辅助块内渲染 Handlebars 变量?

发布于 2025-01-10 19:44:30 字数 704 浏览 0 评论 0原文

我正在尝试获取两个 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}} 不在这里渲染?我需要部分执行此操作吗?

I'm trying to get two Handlebars variables to render inside a custom Handlebars helper I've created.

I'm using the Express.js view engine for handlebars.js, and in my app.js have set up a helper to compare equality:

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);
});

My controller passes two variables to the view:

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

In my-view.hbs I'd like to render the variables if they're equal, so I tried:

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

The result is only foo renders. Why don't {{x}} and {{y}} render here? Do I need to do this with a partial?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦与时光遇 2025-01-17 19:44:30

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

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

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

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

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

为了更好地了解问题所在,您可以在您的代码中 console.log(this)使用两种函数表达式类型的帮助器并比较差异。

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

The reason your template will not render the values of x or y from within your ifEqual block is because there are no x or y properties within the context of that block. The reason that these properties are missing from the context is a very simple one: It is because in your call to registerHelper you used an Arrow Function Expression to define the Helper function.

Arrow Functions Expressions, in addition to a more compact syntax, are different from standard Function Expressions. The important difference in this case is that they do not have their own this context.

When you call registerHelper, Handlebars will bind the helper callback function to the data context of the template, in this case that would be the Object: { x: 3, y: 3 }. However, this will only work if you use a regular Function Expression as your callback and not an Arrow Function Expression - as the Arrow Function Expression cannot be dynamically bound to a different this context.

This means that you must use a regular function expression as your argument to registerHelper:

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

To get a better sense of what is wrong, you could console.log(this) within your helper using both function expression types and compare the difference.

I have created a fiddle to demonstrate the difference.

只是一片海 2025-01-17 19:44:30

好吧,我用不同的方法做到了这一点:

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

然后在我看来:

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

Ok so I've done this with a different approach:

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

Then in my view:

{{#renderVars x y}}
{{/renderVars}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文