问题
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