简体   繁体   English

handlebars.js {{#if}} 条件中的逻辑运算符

[英]Logical operator in a handlebars.js {{#if}} conditional

Is there a way in handlebars JS to incorporate logical operators into the standard handlebars.js conditional operator? handlebars JS 中是否有一种方法可以将逻辑运算符合并到标准 handlebars.js 条件运算符中? Something like this:像这样:

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

I know I could write my own helper, but first I'd like to make sure I'm not reinventing the wheel.我知道我可以编写自己的助手,但首先我想确保我没有重新发明轮子。

This is possible by 'cheating' with a block helper.这可以通过使用块助手“作弊”来实现。 This probably goes against the Ideology of the people who developed Handlebars.这可能与开发 Handlebars 的人的意识形态背道而驰。

Handlebars.registerHelper('ifCond', function(v1, v2, options) {
  if(v1 === v2) {
    return options.fn(this);
  }
  return options.inverse(this);
});

You can then call the helper in the template like this然后您可以像这样调用模板中的助手

{{#ifCond v1 v2}}
    {{v1}} is equal to {{v2}}
{{else}}
    {{v1}} is not equal to {{v2}}
{{/ifCond}}

Taking the solution one step further.将解决方案更进一步。 This adds the compare operator.这添加了比较运算符。

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

Use it in a template like this:在这样的模板中使用它:

{{#ifCond var1 '==' var2}}

Coffee Script version咖啡脚本版本

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

Handlebars supports nested operations. Handlebars 支持嵌套操作。 This provides a lot of flexibility (and cleaner code) if we write our logic a little differently.如果我们以稍微不同的方式编写我们的逻辑,这会提供很大的灵活性(和更清晰的代码)。

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

In fact, we can add all sorts of logic:其实我们可以添加各种逻辑:

{{#if (or 
        (eq section1 "foo")
        (ne section2 "bar"))}}
.. content
{{/if}}

Just register these helpers:只需注册这些助手:

Handlebars.registerHelper({
    eq: (v1, v2) => v1 === v2,
    ne: (v1, v2) => v1 !== v2,
    lt: (v1, v2) => v1 < v2,
    gt: (v1, v2) => v1 > v2,
    lte: (v1, v2) => v1 <= v2,
    gte: (v1, v2) => v1 >= v2,
    and() {
        return Array.prototype.every.call(arguments, Boolean);
    },
    or() {
        return Array.prototype.slice.call(arguments, 0, -1).some(Boolean);
    }
});

taking this one up a notch, for those of you who live on the edge.对于那些生活在边缘的人来说,把这个提升一个档次。

gist : https://gist.github.com/akhoury/9118682 Demo : Code snippet below要点https : //gist.github.com/akhoury/9118682演示:下面的代码片段

Handlebars Helper: {{#xif EXPRESSION}} {{else}} {{/xif}} {{#xif EXPRESSION}} {{else}} {{/xif}}助手: {{#xif EXPRESSION}} {{else}} {{/xif}}

a helper to execute an IF statement with any expression使用任何表达式执行 IF 语句的助手

  1. EXPRESSION is a properly escaped String EXPRESSION 是一个正确转义的字符串
  2. Yes you NEED to properly escape the string literals or just alternate single and double quotes是的,您需要正确转义字符串文字或仅交替使用单引号和双引号
  3. you can access any global function or property ie encodeURIComponent(property)您可以访问任何全局函数或属性,即encodeURIComponent(property)
  4. this example assumes you passed this context to your handlebars template( {name: 'Sam', age: '20' } ) , notice age is a string , just for so I can demo parseInt() later in this post这个例子假设你将此上下文传递给你的把手template( {name: 'Sam', age: '20' } ) ,注意age是一个string ,只是为了我可以在这篇文章的后面演示parseInt()

Usage:用法:

<p>
 {{#xif " name == 'Sam' && age === '12' " }}
   BOOM
 {{else}}
   BAMM
 {{/xif}}
</p>

Output输出

<p>
  BOOM
</p>

JavaScript: (it depends on another helper- keep reading) JavaScript:(这取决于另一个助手-继续阅读)

 Handlebars.registerHelper("xif", function (expression, options) {
    return Handlebars.helpers["x"].apply(this, [expression, options]) ? options.fn(this) : options.inverse(this);
  });

Handlebars Helper: {{x EXPRESSION}}车把助手: {{x EXPRESSION}}

A helper to execute javascript expressions执行javascript表达式的助手

  1. EXPRESSION is a properly escaped String EXPRESSION 是一个正确转义的字符串
  2. Yes you NEED to properly escape the string literals or just alternate single and double quotes是的,您需要正确转义字符串文字或仅交替使用单引号和双引号
  3. you can access any global function or property ie parseInt(property)您可以访问任何全局函数或属性,即parseInt(property)
  4. this example assumes you passed this context to your handlebars template( {name: 'Sam', age: '20' } ) , age is a string for demo purpose, it can be anything..此示例假设您将此上下文传递给您的车把template( {name: 'Sam', age: '20' } )age是用于演示目的的string ,它可以是任何东西..

Usage:用法:

<p>Url: {{x "'hi' + name + ', ' + window.location.href + ' <---- this is your href,' + ' your Age is:' + parseInt(this.age, 10)"}}</p>

Output:输出:

<p>Url: hi Sam, http://example.com <---- this is your href, your Age is: 20</p>

JavaScript: JavaScript:

This looks a little large because I expanded syntax and commented over almost each line for clarity purposes这看起来有点大,因为为了清晰起见,我扩展了语法并注释了几乎每一行

 Handlebars.registerHelper("x", function(expression, options) { var result; // you can change the context, or merge it with options.data, options.hash var context = this; // yup, i use 'with' here to expose the context's properties as block variables // you don't need to do {{x 'this.age + 2'}} // but you can also do {{x 'age + 2'}} // HOWEVER including an UNINITIALIZED var in a expression will return undefined as the result. with(context) { result = (function() { try { return eval(expression); } catch (e) { console.warn('•Expression: {{x \\'' + expression + '\\'}}\\n•JS-Error: ', e, '\\n•Context: ', context); } }).call(context); // to make eval's lexical this=context } return result; }); Handlebars.registerHelper("xif", function(expression, options) { return Handlebars.helpers["x"].apply(this, [expression, options]) ? options.fn(this) : options.inverse(this); }); var data = [{ firstName: 'Joan', age: '21', email: 'joan@aaa.bbb' }, { firstName: 'Sam', age: '18', email: 'sam@aaa.bbb' }, { firstName: 'Perter', lastName: 'Smith', age: '25', email: 'joseph@aaa.bbb' }]; var source = $("#template").html(); var template = Handlebars.compile(source); $("#main").html(template(data));
 h1 { font-size: large; } .content { padding: 10px; } .person { padding: 5px; margin: 5px; border: 1px solid grey; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.min.js"></script> <script id="template" type="text/x-handlebars-template"> <div class="content"> {{#each this}} <div class="person"> <h1>{{x "'Hi ' + firstName"}}, {{x 'lastName'}}</h1> <div>{{x '"you were born in " + ((new Date()).getFullYear() - parseInt(this.age, 10)) '}}</div> {{#xif 'parseInt(age) >= 21'}} login here: <a href="http://foo.bar?email={{x 'encodeURIComponent(email)'}}"> http://foo.bar?email={{x 'encodeURIComponent(email)'}} </a> {{else}} Please go back when you grow up. {{/xif}} </div> {{/each}} </div> </script> <div id="main"></div>

Moar摩尔

if you want access upper level scope, this one is slightly different, the expression is the JOIN of all arguments, usage: say context data looks like this:如果你想访问上层范围,这个略有不同,表达式是所有参数的 JOIN,用法:说上下文数据看起来像这样:

// data
{name: 'Sam', age: '20', address: { city: 'yomomaz' } }

// in template
// notice how the expression wrap all the string with quotes, and even the variables
// as they will become strings by the time they hit the helper
// play with it, you will immediately see the errored expressions and figure it out

{{#with address}}
    {{z '"hi " + "' ../this.name '" + " you live with " + "' city '"' }}
{{/with}}

Javascript: Javascript:

Handlebars.registerHelper("z", function () {
    var options = arguments[arguments.length - 1]
    delete arguments[arguments.length - 1];
    return Handlebars.helpers["x"].apply(this, [Array.prototype.slice.call(arguments, 0).join(''), options]);
});

Handlebars.registerHelper("zif", function () {
    var options = arguments[arguments.length - 1]
    delete arguments[arguments.length - 1];
    return Handlebars.helpers["x"].apply(this, [Array.prototype.slice.call(arguments, 0).join(''), options]) ? options.fn(this) : options.inverse(this);
});

There is a simple way of doing this without writing a helper function... It can be done within the template completely.有一种简单的方法可以在不编写辅助函数的情况下执行此操作......它可以完全在模板中完成。

{{#if cond1}}   
  {{#if con2}}   
    <div> and condition completed</div>  
  {{/if}}
{{else}}   
  <div> both conditions weren't true</div>  
{{/if}}

Edit: Conversely you can do or's by doing this:编辑:相反,您可以通过执行以下操作来执行或操作:

{{#if cond1}}  
  <div> or condition completed</div>    
{{else}}   
  {{#if cond2}}  
    <div> or condition completed</div>  
  {{else}}      
    <div> neither of the conditions were true</div>    
  {{/if}}  
{{/if}}

Edit/Note: From the handlebar's website: handlebarsjs.com here are the falsy values:编辑/注意:从车把的网站:handlebarsjs.com 这里是虚假值:

You can use the if helper to conditionally render a block.您可以使用 if 帮助器有条件地渲染块。 If its argument returns false, undefined, null, "" or [] (a "falsy" value), Then any 'cond' (like cond1 or cond2) will not be counted as true.如果其参数返回 false、undefined、null、"" 或 [](“falsy”值),则任何“cond”(如 cond1 或 cond2)都不会被视为真。

One problem with all of the answers posted here is that they don't work with bound properties, ie the if condition is not re-evaluated when the properties involved change.此处发布的所有答案的一个问题是它们不适用于绑定属性,即当所涉及的属性发生更改时不会重新评估 if 条件。 Here's a slightly more advanced version of the helper supporting bindings.这是支持绑定的助手的稍微高级的版本。 It uses the bind function from the Ember source, which is also used to implement the normal Ember #if helper.它使用来自 Ember 源代码的bind函数,该函数也用于实现普通的 Ember #if助手。

This one is limited to a single bound property on the left-hand side, comparing to a constant on the right-hand side, which I think is good enough for most practical purposes.与右侧的常量相比,这个仅限于左侧的单个绑定属性,我认为这对于大多数实际用途来说已经足够了。 If you need something more advanced than a simple comparison, then perhaps it would be good to start declaring some computed properties and using the normal #if helper instead.如果您需要比简单比较更高级的东西,那么开始声明一些计算属性并使用普通的#if助手可能会更好。

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

You can use it like this:你可以这样使用它:

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

Improved solution that basically work with any binary operator (at least numbers, strings doesn't work well with eval, TAKE CARE OF POSSIBLE SCRIPT INJECTION IF USING A NON DEFINED OPERATOR WITH USER INPUTS):改进的解决方案基本上适用于任何二元运算符(至少数字、字符串不适用于 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);
    }
});

Here's a solution if you want to check multiple conditions:如果您想检查多个条件,这是一个解决方案:

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

Usage:用法:

/* if(list.length>0 && public){}*/

{{#checkIf list.length '>' 0 '&&' public '==' true}} <p>condition satisfied</p>{{/checkIf}}

Here's a link to the block helper I use: comparison block helper .这是我使用的块助手的链接: 比较块助手 It supports all the standard operators and lets you write code as shown below.它支持所有标准运算符,并允许您编写如下所示的代码。 It's really quite handy.这真的很方便。

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

Similar to Jim's answer but a using a bit of creativity we could also do something like this:类似于吉姆的回答,但使用一点创造力,我们也可以做这样的事情:

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

Then to use it we get something like:然后使用它,我们得到类似的东西:

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

I would suggest moving the object out of the function for better performance but otherwise you can add any compare function you want, including "and" and "or".我建议将对象移出函数以获得更好的性能,否则您可以添加所需的任何比较函数,包括“and”和“or”。

Install Ember Truth Helpers addon by running the below command通过运行以下命令安装Ember Truth Helpers插件

ember install ember-truth-helpers ember 安装 ember-truth-helpers

you can start use most of the logical operators(eq,not-eq,not,and,or,gt,gte,lt,lte,xor).您可以开始使用大多数逻辑运算符(eq、not-eq、not、and、or、gt、gte、lt、lte、xor)。

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

You can even include subexpression to go further,您甚至可以包含子表达式以走得更远,

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

Yet another crooked solution for a ternary helper:三元助手的另一个错误解决方案:

'?:' ( condition, first, second ) {
  return condition ? first : second;
}

<span>{{?: fooExists 'found it' 'nope, sorry'}}</span>

Or a simple coalesce helper:或者一个简单的合并助手:

'??' ( first, second ) {
  return first ? first : second;
}

<span>{{?? foo bar}}</span>

Since these characters don't have a special meaning in handlebars markup, you're free to use them for helper names.由于这些字符在车把标记中没有特殊含义,因此您可以自由地将它们用作助手名称。

One other alternative is to use function name in #if .另一种选择是在#if使用函数名称。 The #if will detect if the parameter is function and if it is then it will call it and use its return for truthyness check. #if将检测参数是否为函数,如果是,则调用它并使用其返回值进行真实性检查。 Below myFunction gets current context as this .在 myFunction 下面获取当前上下文作为this

{{#if myFunction}}
  I'm Happy!
{{/if}}

Unfortunately none of these solutions solve the problem of "OR" operator "cond1 || cond2".不幸的是,这些解决方案都没有解决“或”运算符“cond1 || cond2”的问题。

  1. Check if first value is true检查第一个值是否为真
  2. Use "^" (or) and check if otherwise cond2 is true使用“^”(或)并检查 cond2 是否为真

    {{#if cond1}} DO THE ACTION {{^}} {{#if cond2}} DO THE ACTION {{/if}} {{/if}} {{#if cond1}} 做动作 {{^}} {{#if cond2}} 做动作 {{/if}} {{/if}}

It breaks DRY rule.它打破了 DRY 规则。 So why not use partial to make it less messy那么为什么不使用部分来使它不那么凌乱

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

I can understand why you would want to create a helper for situations where you have a large number of varied comparisons to perform within your template, but for a relatively small number of comparisons (or even one, which was what brought me to this page in the first place), it would probably just be easier to define a new handlebars variable in your view-rendering function call, like:我可以理解为什么您要为在模板中执行大量不同比较的情况创建一个帮助程序,但要进行相对较少的比较(甚至是一个比较,这就是将我带到此页面的原因)首先),在视图渲染函数调用中定义一个新的 handlebars 变量可能会更容易,例如:

Pass to handlebars on render:在渲染时传递到把手:

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

and then within your handlebars template:然后在您的把手模板中:

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

I mention this for simplicity's sake, and also because it's an answer that may be quick and helpful while still complying with the logicless nature of Handlebars.我提到这一点是为了简单起见,也因为它是一个快速且有用的答案,同时仍然符合 Handlebars 的无逻辑性质。

I have found a npm package made with CoffeeScript that has a lot of incredible useful helpers for Handlebars.我发现了一个用 CoffeeScript 制作的 npm 包,它有很多非常有用的 Handlebars 助手。 Take a look of the documentation in the following URL:查看以下 URL 中的文档:

https://npmjs.org/package/handlebars-helpers https://npmjs.org/package/handlebars-helpers

You can do a wget http://registry.npmjs.org/handlebars-helpers/-/handlebars-helpers-0.2.6.tgz to download them and see the contents of the package.您可以执行wget http://registry.npmjs.org/handlebars-helpers/-/handlebars-helpers-0.2.6.tgz来下载它们并查看包的内容。

You will be abled to do things like {{#is number 5}} or {{formatDate date "%m/%d/%Y"}}您将能够执行{{#is number 5}}{{formatDate date "%m/%d/%Y"}}

if you just want to check if one or the other element are present you can use this custom helper如果您只想检查一个或另一个元素是否存在,您可以使用此自定义助手

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

like this像这样

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

if you also need to be able to have an "or" to compare function return values I would rather add another property that returns the desired result.如果您还需要能够使用“或”来比较函数返回值,我宁愿添加另一个返回所需结果的属性。

The templates should be logicless after all!毕竟模板应该是没有逻辑的!

For those having problems comparing object properties, inside the helper add this solution对于那些在比较对象属性时遇到问题的人,请在助手中添加此解决方案

Ember.js helper not properly recognizing a parameter Ember.js 助手无法正确识别参数

Here we have vanilla handlebars for multiple logical && and ||这里我们有用于多个逻辑 && 和 || 的普通把手(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

Not so sure if it's "safe" to use "and" and "or"... maybe change to something like "op_and" and "op_or"?不太确定使用“and”和“or”是否“安全”......也许可以更改为“op_and”和“op_or”之类的东西?

Just came to this post from a google search on how to check if a string equals another string.刚刚从谷歌搜索到如何检查一个字符串是否等于另一个字符串的这篇文章。

I use HandlebarsJS in NodeJS server-side, but I also use the same template files on the front-end using the browser version of HandlebarsJS to parse it.我在 NodeJS 服务端使用 HandlebarsJS,但我也在前端使用相同的模板文件使用 HandlebarsJS 的浏览器版本来解析它。 This meant that if I wanted a custom helper, I'd have to define it in 2 separate places, or assign a function to the object in question - too much effort!!这意味着如果我想要一个自定义助手,我必须在 2 个不同的地方定义它,或者为有问题的对象分配一个函数 - 太费力了!!

What people forget is that certain objects have inherit functions that can be used in the moustache template.人们忘记的是某些对象具有可以在 mustache 模板中使用的继承函数。 In the case of a string:在字符串的情况下:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match

An Array containing the entire match result and any parentheses-captured matched results; null if there were no matches.

We can use this method to return either an array of matches, or null if no matches were found.我们可以使用此方法返回匹配数组,如果未找到匹配,则返回null This is perfect, because looking at the HandlebarsJS documentation http://handlebarsjs.com/builtin_helpers.html这是完美的,因为查看 HandlebarsJS 文档http://handlebarsjs.com/builtin_helpers.html

You can use the if helper to conditionally render a block. If its argument returns false, undefined, null, "", 0, or [], Handlebars will not render the block.

So...所以...

{{#if your_string.match "what_youre_looking_for"}} 
String found :)
{{else}}
No match found :(
{{/if}}

UPDATE:更新:

After testing on all browsers, this doesn't work on Firefox .在所有浏览器上测试后,这在 Firefox 上不起作用 HandlebarsJS passes other arguments to a function call, meaning that when String.prototype.match is called, the second argument (ie the Regexp flags for the match function call as per above documentation) appears to be being passed. HandlebarsJS 将其他参数传递给函数调用,这意味着当 String.prototype.match 被调用时,第二个参数(即上述文档中匹配函数调用的 Regexp 标志)似乎正在被传递。 Firefox sees this as a deprecated use of String.prototype.match, and so breaks. Firefox 认为这是不推荐使用的 String.prototype.match,因此中断。

A workaround is to declare a new functional prototype for the String JS object , and use that instead:一种解决方法是为 String JS object 声明一个新的功能原型,并使用它:

if(typeof String.includes !== 'function') {
    String.prototype.includes = function(str) {
        if(!(str instanceof RegExp))
            str = new RegExp((str+'').escapeRegExp(),'g');
        return str.test(this);
    }
}

Ensure this JS code is included before you run your Handlebars.compile() function, then in your template...确保运行 Handlebars.compile() 函数之前包含此 JS 代码,然后在模板中...

{{#your_string}}
    {{#if (includes "what_youre_looking_for")}} 
        String found :)
    {{else}}
        No match found :(
    {{/if}}
{{/your_string}}

You can do it simply by using the logical operator like this shown below:您只需使用如下所示的逻辑运算符即可完成此操作:

{{#if (or(eq firstValue 'String_to_compare_value') (eq secondValue 'String_to_compare_value'))}}business logic goes here{{/if}}

{{#if (and(eq firstValue 'String_to_compare_value') (eq secondValue 'String_to_compare_value'))}}business logic goes here{{/if}}

Before closing if you can write your business logic在关闭之前,如果您可以编写业务逻辑

Correct Solution for AND/OR 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);
}); 

Then call as follows然后调用如下

{{#if (or (eq questionType 'STARTTIME') (eq questionType 'ENDTIME') (..) ) }}

BTW: Note that the solution given here is incorrect, he's not subtracting the last argument which is the function name.顺便说一句:请注意,这里给出的解决方案是不正确的,他没有减去最后一个参数,即函数名称。 https://stackoverflow.com/a/31632215/1005607 https://stackoverflow.com/a/31632215/1005607

His original AND/OR was based on the full list of arguments他最初的 AND/OR 是基于完整的参数列表

   and: function () {
        return Array.prototype.slice.call(arguments).every(Boolean);
    },
    or: function () {
        return Array.prototype.slice.call(arguments).some(Boolean);
    }

Can someone change that answer?有人可以更改该答案吗? I just wasted an hour trying to fix something in an answer recommended by 86 people.我只是浪费了一个小时试图修复 86 人推荐的答案中的某些内容。 The fix is to filter out the last argument which is the function name.解决方法是过滤掉最后一个参数,即函数名称。 Array.prototype.slice.call(arguments, 0, arguments.length - 1)

Following these 2 guides a-way-to-let-users-define-custom-made-bound-if-statements and custom bound helpers I was able to adjust my shared views in this post on stackoverflow to use this instead of the standard #if statement.遵循这两个指南a-way-to-let-users-define-custom-made-bound-if-statementscustom bound -if-statements自定义绑定助手,我能够在stackoverflow上的这篇文章中调整我的共享视图以使用它而不是标准#如果语句。 This should be more secure than just tossing an #if in there.这应该比只是在那里扔一个 #if 更安全。

The custom bound helpers in that gist are outstanding.该要点中的自定义绑定助手非常出色。

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

I am using the ember cli project to build my ember application.我正在使用ember cli项目来构建我的 ember 应用程序。

Current setup at the time of this post:撰写本文时的当前设置:

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

In Ember.js you can use inline if helper in if block helper.在 Ember.js 中,您可以在 if 块助手中使用内联 if助手。 It can replace ||它可以代替|| logical operator, for example:逻辑运算符,例如:

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

You can use the following code:您可以使用以下代码:

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

you cannot write your expressions inside handlebars template but all of your logic (expressions) in express.js您不能在车把模板中编写表达式,而是在 express.js 中编写所有逻辑(表达式)

app.js<\/strong>应用程序.js<\/strong>

res.render("view.hbs", {expression: section1 || section2})

Here's an approach I'm using for ember 1.10 and ember-cli 2.0.这是我用于 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));
});

Then you can use it in your templates like this:然后你可以在你的模板中使用它,如下所示:

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

Where the arguments to the expression are passed in as p0 , p1 , p2 etc and p0 can also be referenced as this .其中表达式的参数作为p0p1p2等传入,并且p0也可以作为this引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM