问题
The following was proposed as a logical AND/OR multi-arg Handlebars.JS helper:
Handlebars.registerHelper({
and: function () {
return Array.prototype.slice.call(arguments).every(Boolean);
},
or: function () {
return Array.prototype.slice.call(arguments).some(Boolean);
}
});
Handlebars.js Else If
This doesn't work for me because I need to call it as
{{#if (or questionType 'STARTTIME' 'ENDTIME') }}
{{#if (or questionType 'STARTTIME' 'ENDTIME' 'ARGUMENT3' 'ARGUMENT4') }}
In other words,
- I support multiple args for my AND/OR,
The first arg is always what I'm checking, e.g.
return (questionType == arg1 || questionType == arg2 || questionType == arg3 ...)
In other words, I can't write a dumb 2-param or(..) / and(..) like this,
Handlebars.registerHelper('or', function(a, b, c) {
if(a == b || a == c)
return true;
else
return false;
});
It should be multi-argument, with the first one always being checked. Any thoughts?
回答1:
First: Your original or
helper is not going to work. Handlebars passes an additional meta object as the final argument when invoking a helper. For example, using your or
helper in a template as (or false false)
results in the helper function being executed with the following arguments
object:
{
0: false,
1: false,
2: {
"name": "or",
"hash": {...},
"data": {...}
},
length: 3
}
The existence of that Object at 3
will evaluate to true
in the Boolean
conversion and cause your helper to return true
despite that the call site passes only false
values.
To make the helper work as intended, we need to exclude the last arg when slicing our arguments
object. (FYI: The purpose of the slice
is to convert the array-like arguments
Object to an Array, so that we may call Array.prototype methods on it, like .some
.) To do this, we update our or
helper to be:
return Array.prototype.slice.call(arguments, 0, -1).some(Boolean);
Now we can turn to the problem of comparing our first argument expression to the rest. We can similarly update our .slice
call to exclude the first argument as well: .slice.call(arguments, 1, -1)
. Then we need only to compare each item in the slice to the first argument. Our helper becomes:
return Array.prototype.slice.call(arguments, 1, -1).some(arg => arg === arguments[0]);
Our helper now works as we intend; but I would urge you to rename it as it not an "or" operation, but an "in".
来源:https://stackoverflow.com/questions/50190854/logical-or-and-handlebars-js-helper-multiple-arguments-first-one-always-being