在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)

其他回答

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

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

与Jim的答案类似,但我们也可以使用一点创造力,这样做:

Handlebars.registerHelper( "compare", function( v1, op, v2, options ) {
        
  var c = {
    "eq": function( v1, v2 ) {
      return v1 == v2;
    },
    "neq": function( v1, v2 ) {
      return v1 != v2;
    },
    ...
  }
        
  if( Object.prototype.hasOwnProperty.call( c, op ) ) {
    return c[ op ].call( this, v1, v2 ) ? options.fn( this ) : options.inverse( this );
  }
  return options.inverse( this );
} );

然后使用它,我们得到如下内容:

{{#compare numberone "eq" numbertwo}}
  do something
{{else}}
  do something else
{{/compare}}

我建议将对象移出函数以获得更好的性能,否则您可以添加任何您想要的比较函数,包括“and”和“or”。

通过运行以下命令安装烬真相助手插件

Ember安装Ember -truth-helpers

您可以开始使用大多数逻辑运算符(eq,not-eq,not,and,or,gt,gte,lt,lte,xor)。

{{#if (or section1 section2)}}  
...content  
{{/if}}

你甚至可以包含子表达式来更进一步,

{{#if (or (eq section1 "section1") (eq section2 "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)

如果您只是想检查一个元素或另一个元素是否存在,您可以使用这个自定义帮助器

Handlebars.registerHelper('if_or', function(elem1, elem2, options) {
  if (Handlebars.Utils.isEmpty(elem1) && Handlebars.Utils.isEmpty(elem2)) {
    return options.inverse(this);
  } else {
    return options.fn(this);
  }
});

像这样

{{#if_or elem1 elem2}}
  {{elem1}} or {{elem2}} are present
{{else}}
  not present
{{/if_or}}

如果你还需要能够有一个“或”来比较 函数返回值 我宁愿添加另一个返回所需结果的属性。

模板应该是无逻辑的!