使用把手迭代javascript对象

我正在尝试使用Handlebars注册帮助程序以允许迭代JSON对象。 这个要点看起来是一个合适的解决方案。 我将其转换为以下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 gem 'handlebars-assets'将一个把手添加到rails应用程序中。

您的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并且for(;;)循环的JavaScript将不会迭代。

您还应该使用own而不是hasOwnProperty

如果您只想迭代在对象本身上定义的键,通过添加hasOwnProperty检查以避免可能从原型中插入的属性,使用for own key, value of object

但这更多是为了方便而不是正确。

另外,CoffeeScript循环是表达式,所以你通常会说array = expr for own k, v in o或等价forms:

 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('') 

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