Handlebars.js - 每个和吸气剂

时间:2012-11-02 22:11:22

标签: function loops each handlebars.js getter

我正在使用Handlebars.js并遇到了一个我无法解决的问题。

我想在模板中迭代一个数组,但问题是我用于迭代器的表达式是一个getter而不是一个数组。

说明问题的一段代码如下:

HTML:

<script id="template" type="text/x-handlebars">
    Accessing directly: {{array}} <br/>
    Accessing by getter: {{getArray}} <br/>

    <br/>

    Looping directly:
    <ul>
    {{#each array}}
        <li>{{this}}</li>
    {{/each}}
    </ul>

    <br/>

    Looping by getter:
    <ul>
    {{#each getArray}}
        <li>{{this}}</li>
    {{/each}}
    </ul>
</script>

<p id="content"></p>

JS:

var template = Handlebars.compile($("#template").html());
var element = {
    array: [0, 1, 2],

    getArray: function() {
        return this.array;
    }
};

$("#content").html(template(element));

问题是使用getter的each什么都不做。这可以在jsFiddle中找到。

使用getter有没有干净的方法来执行此操作,还是应该编写辅助函数或类似辅助函数的东西?

谢谢!

2 个答案:

答案 0 :(得分:7)

{{#each}}需要一个数组,它不会理解任何其他内容。您可以为此添加一个简单的自定义帮助程序,如果您希望这样,您只需记住使用fn.call(this)

getArray: function() {
    return this.array;
}

拥有正确的this。像这样的东西可能会成功:

Handlebars.registerHelper('smart_each', function(a, block) {
    if(typeof a == 'function')
        a = a.call(this);
    var s = '';
    for(var i = 0; i < a.length; ++i)
        s += block(a[i]);
    return s;
});

演示:http://jsfiddle.net/ambiguous/yuPfD/

您可能希望查看Handlebars源代码中的{{#each}}实现,以便稍微修改一下,但我会将其作为练习。

答案 1 :(得分:0)

如果您使用proper JavaScript getters,您的技术将起作用。这是使用ES6中提供的类的示例。有关以下代码的ES5示例,请参阅this version which uses babel.io's repl

'use strict'

const handlebars = require('handlebars')
const template = "{{#each letters}} {{this}} {{/each}}"
var context

class Alphabet {
  get letters() {
    return 'abc'.split('')
  }
}

context = new Alphabet()
console.log('class instance with getter methods:')
console.log(handlebars.compile(template)(context))


context = {
  letters: 'xyz'.split('')
}

console.log('regular object:')
console.log(handlebars.compile(template)(context))

输出:

❯ node index.js
class instance with getter methods:
 a  b  c 
regular object:
 x  y  z