0

以下是作为逻辑 AND/OR 多参数 Handlebars.JS 助手提出的:

Handlebars.registerHelper({
    and: function () {
        return Array.prototype.slice.call(arguments).every(Boolean);
    },
    or: function () {
        return Array.prototype.slice.call(arguments).some(Boolean);
    }
});

Handlebars.js 否则如果

这对我不起作用,因为我需要将其称为

{{#if (or questionType 'STARTTIME' 'ENDTIME') }}

{{#if (or questionType 'STARTTIME' 'ENDTIME' 'ARGUMENT3' 'ARGUMENT4') }}

换句话说,

  1. 我的 AND/OR 支持多个参数,
  2. 第一个arg始终是我正在检查的内容,例如

    return (questionType == arg1 || questionType == arg2 || questionType == arg3 ...)

换句话说,我不能像这样写一个愚蠢的 2-param or(..) / and(..),

Handlebars.registerHelper('or', function(a, b, c) {
    if(a == b || a == c)
        return true;
    else
        return false;
});

它应该是多参数,始终检查第一个参数。有什么想法吗?

4

1 回答 1

1

第一:你原来or的助手是行不通的。Handlebars 在调用帮助程序时传递一个额外的元对象作为最终参数。例如,or在模板中使用您的帮助程序会导致使用以下对象(or false false)执行帮助程序函数:arguments

{
    0: false,
    1: false,
    2: {
        "name": "or",
        "hash": {...},
        "data": {...}
    },
    length: 3
}

尽管调用站点仅传递值,但该对象的存在将在转换中3评估为并导致您的助手返回。trueBooleantruefalse

为了使助手按预期工作,我们需要在切片arguments对象时排除最后一个参数。(仅供参考: 的目的slice是将类似数组的argumentsObject 转换为 Array,以便我们可以在其上调用 Array.prototype 方法,例如.some。)为此,我们将or帮助器更新为:

return Array.prototype.slice.call(arguments, 0, -1).some(Boolean);

现在我们可以转向将我们的第一个参数表达式与其余参数表达式进行比较的问题。我们也可以类似地更新我们的.slice调用以排除第一个参数:.slice.call(arguments, 1, -1). 然后我们只需要将切片中的每个项目与第一个参数进行比较。我们的助手变成:

return Array.prototype.slice.call(arguments, 1, -1).some(arg => arg === arguments[0]);

我们的助手现在按我们的意图工作;但我敦促您将其重命名,因为它不是“或”操作,而是“输入”。

于 2018-05-05T19:24:51.223 回答