4

我正在使用 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));

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

是否有任何干净的方法可以使用 getter 执行此操作,或者我应该编写一个帮助程序或类似辅助函数的东西?

谢谢!

4

2 回答 2

8

{{#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/

您可能想查看{{#each}}Handlebars 源代码中的实现以对其进行一些修饰,但我将把它留作练习。

于 2012-11-03T01:17:23.807 回答
1

如果你使用正确的 JavaScript getter,你的技术就会奏效。这是一个使用类的示例,在 ES6 中可用。对于下面代码的 ES5 示例,请参阅使用 babel.io 的 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 
于 2015-12-31T03:19:40.657 回答