使用Rails 3.1和Coffeescript"找不到变量"错误

tan*_*man 22 javascript ruby-on-rails coffeescript

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

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

ReferenceError:找不到变量:indicator_tag

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

(function() { ... }).call(this);
Run Code Online (Sandbox Code Playgroud)

我理解这是针对变量范围的吗?但它可能阻止我的页面使用这些变量吗?在有人要求之前,我确保我的include标签中的javascript路径是正确的.

Dog*_*ert 47

默认情况下,每个CoffeeScript文件都会编译成一个闭包.除非将它们导出到全局变量,否则无法与其他文件中的函数进行交互.我建议做这样的事情:

在每个coffeescript文件的顶部,添加一行代码

window.Application ||= {}
Run Code Online (Sandbox Code Playgroud)

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

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

Application.indicator_tag = (el) ->
  ...
Run Code Online (Sandbox Code Playgroud)

并使用它们

Application.indicator_tag(params)
Run Code Online (Sandbox Code Playgroud)

  • Dogbert的回答是正确的.(请注意,在这种情况下,您也可以使用`this` /`@`将变量导出为全局变量,例如`@indicator_id = ...`,因为CoffeeScript的包装器在全局上下文中被调用).你刚才碰到的原因是早期版本的Rails 3.1禁用了CoffeeScript的包装器.此行为被归类为错误并已修复为RC1:https://github.com/rails/rails/issues/1125 (9认同)

Tra*_*vis 12

如果你有一个非常复杂的JS后端,Dogbert的解决方案是一个很好的方法.但是,如果您只使用了一些功能,那么有一个更简单的解决方案.只需将它们直接添加到窗口对象,如下所示:

window.indicator_tag = (el) ->
  ...
Run Code Online (Sandbox Code Playgroud)

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