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

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

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


当前回答

这里我们有多个逻辑&&和||(和或)的香草手柄:

Handlebars.registerHelper("and",function() {
    var args = Array.prototype.slice.call(arguments);
    var options = args[args.length-1];

    for(var i=0; i<args.length-1; i++){
        if( !args[i] ){
            return options.inverse(this);
        }
    }

    return options.fn(this);
});


Handlebars.registerHelper("or",function() {
    var args = Array.prototype.slice.call(arguments);
    var options = args[args.length-1];

    for(var i=0; i<args.length-1; i++){
        if( args[i] ){
            return options.fn(this);
        }
    }

    return options.inverse(this);
}

// Results
// {{#and foo bar sally bob}} yup {{else}} nope {{/and}} // yup
// {{#or foo bar "" sally bob}} yup {{else}} nope {{/or}} // yup

// {{#and foo bar "" sally bob}} yup {{else}} nope {{/and}} // nope
// {{#or "" "" "" "" ""}} yup {{else}} nope {{/or}} // nope

不太确定使用“and”和“or”是否“安全”…也许可以改成“op_and”和“op_or”之类的?

其他回答

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

/* 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}}

不幸的是,这些解决方案都不能解决“或”操作符“cond1 || cond2”的问题。

检查第一个值是否为真 使用"^"(或)并检查cond2是否为真 {{#如果cond1}} 行动起来 {{^}} {{#如果cond2}} 行动起来 {{/如果}} {{/如果}}

这违反了DRY规则。为什么不用偏微分函数来简化呢

{{#if cond1}}
    {{> subTemplate}}
{{^}}
    {{#if cond2}}
        {{> subTemplate}}
    {{/if}}
{{/if}}

遵循这2个指南-一种让-用户-定义-定制-bound-if-语句和自定义绑定助手的方法,我能够在stackoverflow上的这篇文章中调整我的共享视图,使用这个而不是标准的#if语句。这应该比在那里扔一个#if更安全。

自定义绑定助手在这个要点上是杰出的。

<li>
    <a href="{{unbound view.varProductSocialBlog}}">
        {{#if-equal view.showDiv "true"}}<div>{{/if-equal}}<i class="fa fa-rss-square"></i>{{#if-equal view.showDiv "true"}}</div>{{/if-equal}}
        {{#if-equal view.showTitle "true"}}Blog{{/if-equal}}
    </a>
</li>

我正在使用ember cli项目来构建我的ember应用程序。

本文撰写时的当前设置:

DEBUG: -------------------------------
DEBUG: Ember      : 1.5.1
DEBUG: Ember Data : 1.0.0-beta.7+canary.b45e23ba
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery     : 2.1.1
DEBUG: -------------------------------

我可以理解为什么你想要创建一个helper的情况下,你有大量不同的比较在你的模板中执行,但相对较少的比较(甚至是一个,这是把我带到这个页面的第一个位置),它可能只是更容易定义一个新的句柄变量在你的视图渲染函数调用,如:

传递到渲染手柄:

var context= {
    'section1' : section1,
    'section2' : section2,
    'section1or2' : (section1)||(section2)
};

然后在handlebars模板中:

{{#if section1or2}}
    .. content
{{/if}}

我提到这一点是为了简单起见,也因为这是一个可能快速且有帮助的答案,同时仍然符合Handlebars的无逻辑性质。

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)