Handlebars.js - Each 和 Getter

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

问题是使用getter的each没有任何作用。在这个jsFiddle中可以看到这一点。
是否有任何干净的方法可以使用getter来执行此操作,或者我应该编写一个帮助程序或类似辅助函数的东西?
谢谢!
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/

您可能需要查看Handlebars源代码中的{{#each}}实现来改进一下,但我会把它留作练习。


1

如果您使用 适当的 JavaScript getters,您的技术将起作用。这是一个使用 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 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接