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

◇◆丶佛笑我妖孽 提交于 2020-12-08 04:50:21

问题


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?


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/60884525/how-can-one-render-handlebars-variables-inside-a-custom-helper-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!