【问题标题】:Condition in Handlebars' if statementHandlebars 的 if 语句中的条件
【发布时间】:2014-02-01 09:15:49
【问题描述】:

我开始了解 Handlebars.js,我想向社区提出一个问题。我知道我还有很多东西要学,而且我还在路上,但我想看看这个问题的一个例子。

在 JS 中用对象创建的数组:

var data = 
[
{
    Field: "id",
    Type: "int(11)",
    Null: "NO",
    Key: "PRI",
    Default: null,
    Extra: "auto_increment"
},
{
    Field: "id2",
    Type: "int(131)",
    Null: "N3O",
    Key: "PR3I",
    Default: null,
    Extra: "auto_increment"
}
];

格式是这样的,因为我从服务器收到的 JSON 看起来就像是完全一样的格式,但现在为了测试我不想进行 ajax 调用。

模板:

<table>
        <thead>
        <tr>

        {{#each this}}
           {{#only_once this}}
            {{#key_value this}}
                <th>{{key}}</th>      
            {{/key_value }}
            {{/only_once}}
        {{/each}}

        </tr>    
        </thead>
...

因为对象在一个数组中,所以我必须首先使用{{#each}} 循环数组,然后有一个注册的助手(我在 github 上找到)帮助我获取密钥,因为我只想将它们写到 thead .

没有我的 if 语句它工作正常,用键填写 thead,但是因为有 2 个对象,它会打印出两次名称

我的问题是我只想打印一次,if 可以解决我的问题,即检查数组的索引是否大于 0 以停止打印数据,但是..

.. Handlebars 不支持条件语句,所以像{{#if x &gt; y}} 这样的代码是不可能的。你们认为最好的解决方案是什么?

Handlebars.registerHelper("only_once", function(item, fn){
    var buffer;
    var i = 0;

    if (i > 0) {
        buffer = false;
    }

        i++;

    return buffer;
});

好吧,我试图写一个助手,但我认为我做错了什么。我的理论是,如果模板中的'this'(我认为)指向数组,然后增加i 以检查数组的索引是否> 0,最后我给了我的如果它是真的而不是发回一个假的 - 所以我认为它会告诉如果不运行里面的代码,但我错了。

【问题讨论】:

    标签: javascript handlebars.js


    【解决方案1】:

    正如this other SO answer 中所述以及@SimonBoudrias 在他的回答中提到的那样,由于Handlebars 1.1.0{{@first}} 原生支持{{#each}} 助手。

    因此,您可以打印数组中第一个对象的所有属性名称,只需使用把手本机帮助器,如下所示:

    {{#each array}}
        {{#if {{@first}}}}
            <!-- It is the first object on the array, print the key for each attribute -->
            {{#each this}}
                <th>{{@key}}</th>
            {{/each}}
       {{/if}}
    {{/each}}
    

    关于向 Handlebars 添加条件 if 语句的附加说明:

    Handlebars 是一个无逻辑模板系统,因此它不包含逻辑语句。

    不过,如果你想使用模板和 Handlebars 来解决这个问题,你可以通过编写一个帮助程序来解决这个问题,正如SO answer 中所解释的那样。在你的情况下,助手可能是这样的:

    Handlebars.registerHelper('ifIsZero', function(value, options) {
      if(value === 0) {
        return options.fn(this);
      }
      return options.inverse(this);
    });
    

    然后,您可以在模板中调用它,如下所示,仅当索引等于 0 时才执行某些操作:

    {{#each array}}
        {{#ifIsZero {{@index}}}}
            <!-- @index is equal to 0, do something -->
            <!-- eg. print the key for each attribute of the object using {{@key}} -->
            {{#each object}}
                <th>{{@key}}</th>
            {{/each}}
    
        {{else}}
            <!-- otherwise, do something else -->
    
        {{/ifIsZero}}
    {{/each}}
    

    【讨论】:

    • 这是一个延伸。如果您想这样做,请使用下划线模板。如果您需要较少的逻辑,请使用 Handlebars。
    • @SimonBoudrias:你说得对,这是添加条件 if 语句的延伸,这就是我在答案的第一行中提到它的原因。无论如何,我已经更新了我的答案以使用您在答案中提到的 first 助手,因此建议的解决方案仅使用本机助手。
    【解决方案2】:

    当您循环数组时,Handlebars 会提供帮助。我认为您不需要任何自定义助手。

    • {{ @index }}返回索引(0,1,2...)
    • {{ @key }} 返回键(字段、类型等)
    • {{ @first }} 布尔值来标记这是否是数组中的第一行
    • {{ @last }} 布尔值来标记这是否是数组中的最后一行

    【讨论】:

    • 我在 Handlebars 的文档中看到过,但在控制台上总是报错: Uncaught Error: Parse error on line 7: ...ch this}} {{@index}} -- --------------------^ 期待“ID”,得到“未定义”
    • 我应该用别的东西代替“这个”吗?我尝试使用“数据”,但它无法识别它。在示例中,我只看到在对象内部使用 {{#each}} 来循环遍历数组或其他东西..
    • 循环对象时,使用@key而不是@index
    • 看起来你的数据对象不是你想象的那样。使用{{log this}} 检查实际情况 (doc)。并确保您使用最新的 Handlebars 版本。
    • 哦,是的,该死的,多么愚蠢的错误! :) 我使用了一个来自 github 示例的 CDN,它指向了 Handlebar 的 beta 版本,现在我再次尝试了 @index,它运行良好!虽然我的其他问题仍然存在,所以我将使用 Underscore.js 检查可能性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2013-09-21
    相关资源
    最近更新 更多