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

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

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


当前回答

您可以使用以下代码:

{{#if selection1}}
    doSomething1
{{else}}
   {{#if selection2}}
       doSomething2
   {{/if}}
{{/if}}

其他回答

在Ember.js中,你可以在if块helper中使用内联if helper。它可以替换||逻辑运算符,例如:

{{#if (if firstCondition firstCondition secondCondition)}}
  (firstCondition || (or) secondCondition) === true
{{/if}}

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

传递到渲染手柄:

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

然后在handlebars模板中:

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

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

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

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

下面是我在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。

改进的解决方案,基本上适用于任何二进制操作符(至少数字,字符串不适用于eval,如果使用用户输入的非定义操作符,请注意可能的脚本注入):

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 eval(""+v1+operator+v2)?options.fn(this):options.inverse(this);
    }
});