逻辑OR / AND Handlebars.JS助手,多个参数,第一个始终被检查

以下是作为逻辑AND / OR多arg 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支持多个args,
  2. 第一个arg总是我正在检查的 ,例如

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

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

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

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

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

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

该对象在3处的存在将在Boolean转换中评估为true ,并使您的助手返回true尽管调用站点仅传递false值。

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

 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]); 

我们的助手现在按照我们的意愿行事; 但我会敦促你重命名它,因为它不是“或”操作,而是“in”。