使用把手迭代 javascript 对象
我正在尝试使用 Handlebars 注册帮助程序以允许迭代 JSON 对象.这个要点 看起来是一个合适的解决方案.我将其转换为以下 CoffeeScript.当我使用任何一个帮助程序时,似乎什么都没有发生(对于 vanilla JavaScript 和 CoffeeScript 版本都是如此).有什么想法吗?
I am trying to register helpers with Handlebars to allow iterating over JSON objects. This gist looked like an appropriate solution. I converted that into the following CoffeeScript. Nothing seems to happen when I use either of the helpers (that holds true for both vanilla JavaScript and the CoffeeScript version). Any ideas?
$ ->
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 应用程序.
I am currently using gem 'handlebars-assets' in the Gemfile to add handlebars to a rails app.
推荐答案
你的 JavaScript 到 CoffeeScript 的音译坏了.你不使用 for ... in 来迭代 CoffeeScript 中的对象,你使用 for k,v of ...:
Your JavaScript to CoffeeScript transliteration is broken. You don't use for ... in to iterate over an object in CoffeeScript, you use for k, v of ...:
使用 of 表示理解对象的属性而不是数组中的值.
Use
ofto signal comprehension over the properties of an object instead of the values in an array.
这个 CoffeeScript 循环:
This CoffeeScript loop:
for x in y
...
变成这个 JavaScript:
becomes this JavaScript:
for (_i = 0, _len = y.length; _i < _len; _i++) {
x = a[_i];
...
}
所以如果 y 是一个没有 length 属性的对象,那么 _len 将是 undefined 并且 JavaScriptfor(;;) 循环根本不会迭代.
So if y is an object without a length property, then _len will be undefined and the JavaScript for(;;) loop won't iterate at all.
您还应该使用 own 而不是 hasOwnProperty:
You should also be using own instead of hasOwnProperty:
如果您只想迭代对象本身上定义的键,通过添加 hasOwnProperty 检查以避免可能从原型中插入的属性,请使用 for own对象的键、值.
If you would like to iterate over just the keys that are defined on the object itself, by adding a
hasOwnPropertycheck to avoid properties that may be interited from the prototype, usefor own key, value of object.
但这更多是为了方便而不是正确.
but that's more for convenience than correctness.
此外,CoffeeScript 循环是表达式,因此您通常会说 array = expr for own k, v in o 或等效形式:
Also, CoffeeScript loops are expressions so you'd usually say array = expr for own k, v in o or the equivalent form:
array = for own k, v in o
expr
如果 expr 超过一行或太长而无法理解.
if expr is more than one line or too long to allow for a readable comprehension.
CoffeeScript 中帮助程序的正确且更惯用的版本看起来更像这样:
A correct and more idiomatic version of your helpers in CoffeeScript would look more like this:
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/
相关文章