Rails – 从JavaScript调用CoffeeScript

我正在使用带有CoffeeScript的Rails 3.1并遇到了麻烦。 如何从位于.js.coffee文件中的.js.erb文件中调用函数?

假设.js.coffee中的函数如下:

myName = -> "Bob" 

我想我可以像任何常规的js函数一样调用它,例如:

 var theName = myName(); 

但这似乎不起作用。 有任何想法吗?

或者是否可以在我的.js.erb文件中使用coffeescript来使一切都一样?

您无法直接调用CoffeeScript函数的原因是CoffeeScript在编译时被包装在一个立即调用的函数中。 这样做是为了防止代码污染全局命名空间。

这通常是一个好主意™,但当然你可以在需要时绕过它。 如果您希望在任何地方 (即全局范围) 可以访问函数或其他变量,您可以简单地说

 window.myName = -> "Bob" 

这样,函数直接添加到全局范围,您可以从任何地方调用它作为window.myName() (或简单地作为myName()除非函数被本地阴影所覆盖)。

但是,为了使全局命名空间尽可能干净,最好为自己定义命名空间(就像jQuery一样,将所有内容放入$对象中)。 例如,在您的第一个CoffeeScript或JavaScript文件(即要加载的第一个文件)中,您可以执行类似的操作

 window.myNamespace = {}; 

然后,只要您想在其他地方使用某些内容,就可以将其添加到该命名空间:

 window.myNamespace.myName = -> "Bob" 

然后你可以使用window.myNamespace.myName()或者只是myNamespace.myName()从任何地方调用它。

或者,您可以在所有文件的顶部使用CoffeeScript的“assign if undefined or null”运算符:

 window.myNamespace ?= {} # create myNamespace if it doesn't already exist 

首先评估哪个文件将创建缺少的window.myNamespace对象。 后续代码只会看到它已经存在并跳过赋值。 无论评估顺序如何,点都是,它始终可用。

编辑:使myNamespace低 – camelcase,因为它基本上是一个变量; 不是构造函数/类

附录:您可以通过使用-b/--bare命令行开关来避免函数包装器,但如上所述,包装器是一件好事。