我有以下 CoffeeScript 代码:
for date of dates
Dom.section !->
Dom.div !->
Dom.text if date.attending then 'Y' else 'N'
Dom.onTap !->
Dom.text date.id
转换为以下 JavaScript(根据 coffeescript.org)
var date;
for (date in dates) {
Dom.section(!function() {
return Dom.div(!function() {
Dom.text(date.attending ? 'Y' : 'N');
return Dom.onTap(!function() {
return Dom.text(date.id);
});
});
});
}
不要理会代码到底做了什么,因为我正在使用 Happening 的 API(一个新的对话应用程序,使用它可以在 CoffeeScript 中制作插件),正因为如此,你无论如何都不会理解它。
不过我会解释一下:
dates
是一个长度为 10 的数组,其中包含对象。这些对象包含id
、day
、year
、attending
等键。- 我遍历所有日期并将它们呈现在屏幕上所谓的“部分”中。
- 每个部分都包含多个 div(为简单起见,在上面的示例中只有一个)。
- 上面的 div 包含一些文本。用户参加事件时为“Y”,未参加事件时为“N”。
- 当用户在这个 div 上点击('onTap'-event)时,它会更新本地和共享存储(在上面的示例中它只会添加一些用于调试的文本)。
一切正常,它在正确的部分显示了正确的日期和与会者数量。所以 date
对象包含正确的数据。
问题
我遇到的问题是当我使用 onTap 事件点击 div 时。当我点击它时,它将始终使用呈现的最后日期。假设我有日期 01-12-14
到 10-12-14
。我点击 05-12-14
,它会在屏幕上添加 id 10-12-14 作为文本。经过长时间的头痛和诅咒后,我找到了造成这种情况的原因,但我不知道如何解决。
请参阅 JavaScript 的第一行(第二个代码示例)。如您所见,它正在声明一个全局变量 date
。一切都很好,但当我点击某些东西时,它会引用 date
,但由于 date
已在循环的最后一次迭代中更新,它将始终使用那个编号。
所以。我如何确保 date
在每个迭代循环中保持私有(private)并确保它在事件中使用正确的值?
注意事项
for k, v in dates
也不起作用,因为它也使 k
成为全局变量。所以简单地使用 dates[k].id
是行不通的。
最佳答案
它没有声明全局,只是声明了该代码的全局内容。如果它在一个函数内,它就不会是全局的。
问题与全局变量无关。这是因为闭包是如何工作的。闭包对它们关闭的变量有一个持久引用,而不是它们在创建闭包时的值的副本。因此,您为 onTap
处理程序创建的所有函数都使用相同的单个 date
对象。
为防止这种情况发生,给他们每个人一些他们自己的东西来关闭那些不会改变的东西。如果 dates
是数组,请使用 forEach
。
(熟悉 CoffeeScript 但不熟悉 Happening 的人请注意:->
前面的 !
不是通常的 !
运算符. Happening extends CoffeeScript 这样一个函数是使用 !->
而不是 ->
声明的,Coffeescript 通常具有的隐式返回值不会生成。[With thanks到 Erik Dolor 指出这一点。])
所以:
dates.forEach (date) !->
Dom.section !->
Dom.div !->
Dom.text if date.attending then 'Y' else 'N'
Dom.onTap !->
Dom.text date.id
...变成这个 JavaScript:
dates.forEach(function(date) {
Dom.section(function() {
Dom.div(function() {
Dom.text(date.attending ? 'Y' : 'N');
Dom.onTap(function() {
Dom.text(date.id);
});
});
});
});
现在,为 forEach
回调的每次迭代创建的闭包在该回调迭代的argument date
上关闭,这不会改变。
关于javascript - CoffeeScript 在 `v` 中创建一个 `for v in values` 的全局变量,导致事件引用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27621543/