Logical OR/AND Handlebars.JS Helper, Multiple Arguments, First One Always Being Checked

最后都变了- 提交于 2020-01-06 06:52:14

问题


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,

  1. I support multiple args for my AND/OR,
  2. 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

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