Rails 3.1 和 Coffeescript 出现“找不到变量”错误

Posted

技术标签:

【中文标题】Rails 3.1 和 Coffeescript 出现“找不到变量”错误【英文标题】:"Can't find variable" error with Rails 3.1 and Coffeescript 【发布时间】:2011-08-30 16:56:07 【问题描述】:

我的应用程序中有视图引用了我的 application.js 文件,该文件包含我在整个应用程序中使用的函数。

在使用 3.1 的边缘版本后,我刚刚安装了 Rails 3.1 候选版本。在我安装 RC 之前,我没有遇到任何问题,但现在我收到了这个错误:

ReferenceError:找不到变量:indicator_tag

indicator_tag 是我在 application.js 中定义的一个函数。 我在 javascript 文件中注意到的唯一区别是现在我的所有函数都包含在:

(function()  ... ).call(this);

我知道这是为了变量范围?但它会阻止我的页面使用这些变量吗?在有人问之前,我已经确保我的包含标签中的 javascript 路径是正确的。

【问题讨论】:

您是否尝试从 application.js.coffee 以外的文件中引用 indicator_tag? 不,它在 application.js.coffee 中。 您能粘贴脚本的内容吗? 您正在尝试从视图中的内联脚本调用indicator_tag 不是内联的,而是一个单独的 JavaScript 文件,仅用于该页面。该文件的包含标签在 application.js 的标签之下。这是该文件的内容pastie.org/1957528 【参考方案1】:

默认情况下,每个 CoffeeScript 文件都被编译成一个闭包。您不能与来自不同文件的函数进行交互,除非您将它们导出到全局变量。我建议这样做:

在每个咖啡脚本文件的顶部,添加一行

window.Application ||= 

这将确保始终存在一个全局命名的应用程序。

现在,对于您需要从另一个文件调用的每个函数,将它们定义为

Application.indicator_tag = (el) ->
  ...

并使用

调用他们
Application.indicator_tag(params)

【讨论】:

Dogbert 的回答是正确的。 (请注意,在这种情况下,您也可以使用 this/@ 将变量导出为全局变量,例如 @indicator_id = ...,因为 CoffeeScript 的包装器是在全局上下文中调用的)。您现在遇到的原因是 Rails 3.1 的早期版本禁用了 CoffeeScript 的包装器。此行为被归类为错误并针对 RC1 进行了修复:github.com/rails/rails/issues/1125 如果可以的话,我会给你 10 个 ^s 的答案。非常感谢。【参考方案2】:

如果您有一个非常复杂的 JS 后端,Dogbert 的解决方案是一个很好的选择。但是,如果您只使用少数几个函数,则有一个更简单的解决方案。只需将它们直接添加到 window 对象,如下所示:

window.indicator_tag = (el) ->
  ...

然后您可以在任何地方使用您的函数,而无需将它们包装在另一个对象中。

【讨论】:

将它们包装在另一个对象中有什么不好?如果您想避免键入“应用程序”,请将其称为“应用程序”。无论如何,当您只是阅读代码时,上下文通常非常有用…… 而且,我会添加这个“窗口”。和“@”一样,不是吗?

以上是关于Rails 3.1 和 Coffeescript 出现“找不到变量”错误的主要内容,如果未能解决你的问题,请参考以下文章

CoffeeScript 未在 Rails 3.1 中更新

Rails 3.1 和 Coffeescript 出现“找不到变量”错误

导轨 3.1。如何防止 Rails 使用 CoffeeScript?

如何将dojo工具包与rails 3.1资产管道和coffeescript一起使用?

如何在 Rails 3.1 应用程序中完全禁用 CoffeeScript?

如何在 Rails 3.1 中为 CoffeeScript 使用选项“--bare”?