我正在使用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有没有干净的方法来执行此操作,还是应该编写辅助函数或类似辅助函数的东西?
谢谢!
答案 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