在handlebars JS中是否有一种方法可以将逻辑操作符合并到标准handlebars. JS条件操作符中?就像这样:

{{#if section1 || section2}}
.. content
{{/if}}

我知道我可以编写自己的助手,但首先我想确保我没有重复工作。


当前回答

AND/OR的正确解

Handlebars.registerHelper('and', function () {
    // Get function args and remove last one (function name)
    return Array.prototype.slice.call(arguments, 0, arguments.length - 1).every(Boolean);
});
Handlebars.registerHelper('or', function () {
    // Get function args and remove last one (function name)
    return Array.prototype.slice.call(arguments, 0, arguments.length - 1).some(Boolean);
}); 

然后按如下方式调用

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

顺便说一句:注意,这里给出的解决方案是不正确的,他没有减去最后一个参数,也就是函数名。 https://stackoverflow.com/a/31632215/1005607

他最初的AND/OR是基于完整的论证列表

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

有人能改一下答案吗?我刚刚浪费了一个小时试图修正一个由86人推荐的答案。修复方法是过滤掉函数名的最后一个参数。Array.prototype.slice。调用(arguments, 0, arguments。长度- 1)

其他回答

下面是我在ember 1.10和ember-cli 2.0中使用的方法。

// app/helpers/js-x.js
export default Ember.HTMLBars.makeBoundHelper(function (params) {
  var paramNames = params.slice(1).map(function(val, idx) { return "p" + idx; });
  var func = Function.apply(this, paramNames.concat("return " + params[0] + ";"))
  return func.apply(params[1] === undefined ? this : params[1], params.slice(1));
});

然后你可以像这样在你的模板中使用它:

// used as sub-expression
{{#each item in model}}
  {{#if (js-x "this.section1 || this.section2" item)}}
  {{/if}}
{{/each}}

// used normally
{{js-x "p0 || p1" model.name model.offer.name}}

表达式的参数被传递为p0,p1,p2等,p0也可以被引用为this。

更进一步的解决方案。这将添加比较操作符。

Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {

    switch (operator) {
        case '==':
            return (v1 == v2) ? options.fn(this) : options.inverse(this);
        case '===':
            return (v1 === v2) ? options.fn(this) : options.inverse(this);
        case '!=':
            return (v1 != v2) ? options.fn(this) : options.inverse(this);
        case '!==':
            return (v1 !== v2) ? options.fn(this) : options.inverse(this);
        case '<':
            return (v1 < v2) ? options.fn(this) : options.inverse(this);
        case '<=':
            return (v1 <= v2) ? options.fn(this) : options.inverse(this);
        case '>':
            return (v1 > v2) ? options.fn(this) : options.inverse(this);
        case '>=':
            return (v1 >= v2) ? options.fn(this) : options.inverse(this);
        case '&&':
            return (v1 && v2) ? options.fn(this) : options.inverse(this);
        case '||':
            return (v1 || v2) ? options.fn(this) : options.inverse(this);
        default:
            return options.inverse(this);
    }
});

在模板中使用它,就像这样:

{{#ifCond var1 '==' var2}}

脚本版本

Handlebars.registerHelper 'ifCond', (v1, operator, v2, options) ->
    switch operator
        when '==', '===', 'is'
            return if v1 is v2 then options.fn this else options.inverse this
        when '!=', '!=='
            return if v1 != v2 then options.fn this else options.inverse this
        when '<'
            return if v1 < v2 then options.fn this else options.inverse this
        when '<='
            return if v1 <= v2 then options.fn this else options.inverse this
        when '>'
            return if v1 > v2 then options.fn this else options.inverse this
        when '>='
            return if v1 >= v2 then options.fn this else options.inverse this
        when '&&', 'and'
            return if v1 and v2 then options.fn this else options.inverse this
        when '||', 'or'
            return if v1 or v2 then options.fn this else options.inverse this
        else
            return options.inverse this

这里有一个我使用的块助手的链接:比较块助手。它支持所有标准操作符,并允许您编写如下所示的代码。真的很方便。

{{#compare Database.Tables.Count ">" 5}}
There are more than 5 tables
{{/compare}}

我发现了一个用CoffeeScript制作的npm包,它有很多令人难以置信的有用的把手助手。在下面的URL中查看文档:

https://npmjs.org/package/handlebars-helpers

您可以执行wget http://registry.npmjs.org/handlebars-helpers/-/handlebars-helpers-0.2.6.tgz来下载它们并查看包的内容。

您将能够执行如下操作:{{#is number 5}}或{{formatDate date "%m/%d/%Y"}}

如果你想检查多个条件,这里有一个解决方案:

/* Handler to check multiple conditions
   */
  Handlebars.registerHelper('checkIf', function (v1,o1,v2,mainOperator,v3,o2,v4,options) {
      var operators = {
           '==': function(a, b){ return a==b},
           '===': function(a, b){ return a===b},
           '!=': function(a, b){ return a!=b},
           '!==': function(a, b){ return a!==b},
           '<': function(a, b){ return a<b},
           '<=': function(a, b){ return a<=b},
           '>': function(a, b){ return a>b},
           '>=': function(a, b){ return a>=b},
           '&&': function(a, b){ return a&&b},
           '||': function(a, b){ return a||b},
        }
      var a1 = operators[o1](v1,v2);
      var a2 = operators[o2](v3,v4);
      var isTrue = operators[mainOperator](a1, a2);
      return isTrue ? options.fn(this) : options.inverse(this);
  });

用法:

/* if(list.length>0 && public){}*/

{{#checkIf list.length '>' 0 '&&' public '==' true}} <p>condition satisfied</p>{{/checkIf}}