我正在尝试使用Handlebars注册帮助程序以允许迭代JSON对象。 This gist看起来像是一个合适的解决方案。我将其转换为以下CoffeeScript。当我使用任何一个帮助程序时,似乎没有任何事情发生(对于vanilla JavaScript和CoffeeScript版本都适用)。有什么想法吗?
$ ->
Handlebars.registerHelper "key_value", (obj, fn)->
buffer = ""
key
for key in obj
if obj.hasOwnProperty(key)
buffer += fn({key: key, value: obj[key]})
buffer
Handlebars.registerHelper "each_with_key", (obj, fn)->
context
buffer = ""
key
keyName = fn.hash.key
for key in obj
if obj.hasOwnProperty(key)
context = obj[key]
if keyName
context[keyName] = key
buffer += fn(context)
buffer
在模板中:
{{#key_value categories}}
I'M ALIVE!!
{{/key_value}}
{{#each_with_key categories key="category_id"}}
I'M ALIVE!!
{{/each_with_key}}
我目前在Gemfile中使用gem 'handlebars-assets'
将把手添加到rails应用程序。
答案 0 :(得分:7)
您的JavaScript到CoffeeScript音译被破坏了。您不使用for ... in
在CoffeeScript中迭代对象,而是使用for k, v of ...
:
使用
of
来表示对对象属性的理解,而不是数组中的值。
这个CoffeeScript循环:
for x in y
...
成为这个JavaScript:
for (_i = 0, _len = y.length; _i < _len; _i++) {
x = a[_i];
...
}
因此,如果y
是没有length
属性的对象,那么_len
将为undefined
,并且JavaScript for(;;)
循环根本不会迭代
您还应该使用own
代替hasOwnProperty
:
如果您只想迭代在对象本身上定义的键,通过添加
hasOwnProperty
检查以避免可能从原型中插入的属性,使用for own key, value of object
。
但这更方便而不是正确。
此外,CoffeeScript循环是表达式,因此您通常会说array = expr for own k, v in o
或等效形式:
array = for own k, v in o
expr
如果expr
超过一行或太长而无法理解。
CoffeeScript中帮助者的正确且更惯用的版本看起来更像是这样:
Handlebars.registerHelper "key_value", (obj, fn)->
(fn(key: key, value: value) for own key, value of obj).join('')
Handlebars.registerHelper "each_with_key", (obj, fn)->
key_name = fn.hash.key
buffer = for own key, value of obj
value[key_name] = key
fn(value)
buffer.join('')