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

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

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


当前回答

这里发布的所有答案的一个问题是,它们不能与绑定属性一起工作,即当涉及的属性发生变化时,if条件不会重新计算。下面是稍微高级一点的支持绑定的帮助器版本。它使用来自Ember源的bind函数,该函数也用于实现正常的Ember #if helper。

与右边的常数相比,这一项在左边被限制为一个单一的边界性质,我认为这对于大多数实际目的来说已经足够好了。如果需要比简单比较更高级的东西,那么最好开始声明一些计算属性,并使用普通的# If helper。

Ember.Handlebars.registerHelper('ifeq', function(a, b, options) {
  return Ember.Handlebars.bind.call(options.contexts[0], a, options, true, function(result) {
    return result === b;
  });
});

你可以这样使用它:

{{#ifeq obj.some.property "something"}}
  They are equal!
{{/ifeq}}

其他回答

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

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

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

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

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

模板应该是无逻辑的!

与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”。

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

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”之类的?

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

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

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

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