在handlebars JS中是否有一种方法可以将逻辑操作符合并到标准handlebars. JS条件操作符中?就像这样:
{{#if section1 || section2}}
.. content
{{/if}}
我知道我可以编写自己的助手,但首先我想确保我没有重复工作。
在handlebars JS中是否有一种方法可以将逻辑操作符合并到标准handlebars. JS条件操作符中?就像这样:
{{#if section1 || section2}}
.. content
{{/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: -------------------------------
其他回答
这里发布的所有答案的一个问题是,它们不能与绑定属性一起工作,即当涉及的属性发生变化时,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}}
这可以通过使用block helper来“欺骗”。这可能违背了开发车把的人的意识形态。
Handlebars.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
然后可以像这样调用模板中的helper
{{#ifCond v1 v2}}
{{v1}} is equal to {{v2}}
{{else}}
{{v1}} is not equal to {{v2}}
{{/ifCond}}
更进一步的解决方案。这将添加比较操作符。
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
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)
如果你想检查多个条件,这里有一个解决方案:
/* 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}}