2011-05-27 51 views
32

在Rails的3.1,我试图找出如何移动的几个班的CoffeeScript从我的控制器默认的CoffeeScript文件(home.js.coffee)到另一个文件了,以结构整个一点点。构造咖啡代码?

有谁知道如何“包括”一个CoffeeScript的文件到另一个?

回答

62

你想要做什么是出口功能。举例来说,如果你开始与

class Foo 
    ... 

class Bar extends Foo 
    ... 

,你决定你移动Foo到自己的文件,该文件应该像

class Foo 
    ... 

window.Foo = Foo 

(其中window.Foo = Foo使得Foo一个全球性的),和Bar的文件应该以Sprockets指令开始

#= require Foo 

(假设您已经命名为Foo的文件Foo.js.coffee)。每个文件独立编译为JS,但链轮将确保Bar之前包含Foo

需要注意的是,作为一种快捷方式,你可以摆脱window.Foo = Foo线,而是写

class window.Foo 
    ... 

或者干脆

class @Foo 
    ... 

定义一个名为Foo类附加到的window目的。

+1

伟大的答案Trevor,非常感谢。 – plang 2011-05-30 05:56:18

+6

嘿特雷弗,你写了咖啡书PragProg书!这是一种荣誉... – plang 2011-05-30 12:14:39

+0

没有概率,这是我的所为。 :) – 2011-05-30 17:05:43

0

我不知道这是直接可能(但有人随时纠正我)。

我的理解是,CoffeeScript的解释程序运行链轮合并您的所有资产之前。由于.coffee文件中的注释不会出现在输出中,并且由于Sprockets使用//=代码注释指令来构建所有内容,所以我认为目前还没有办法在CoffeeScript中创建Sprockets指令。

你仍然可以将你的工作分解成多个.coffee文件,并利用一个父指令的javascript文件来组合这些部分(它可能只包含Sprockets指令,就像股票application.js在Rails 3.1中发布的一样) 。使用Sprockets //= require_tree指令,你可以拆分你的CoffeeScript,并且仍然保持你的应用程序的组织性,但是你仍然会在管理Sprockets的时候留下纯朴的Javascript文件。

This问题可能更好一点解释资产的管道。在这里的边缘文档中还有一些Sprockets帮助器:http://edgeapi.rubyonrails.org/classes/ActionView/Helpers/SprocketsHelper.html#method-i-sprockets_javascript_include_tag,但是这会将工作推到可能变得很难看的视图中。

希望有帮助!

+0

不知道链轮是如何工作的,但是'/ * * /'的评论保持在CoffeeScript的输出。 '/ * // = ... * /'会起作用吗? – 2011-05-28 04:40:56

+1

在CoffeeScript代码中,您可以简单地使用'#= ...' – 2011-05-28 13:38:24

6

当使用window对象共享你的代码的不同部分之间的功能可以工作得很好的地方,它可以当你在一个大/复杂的代码库工作得有点丑陋。此外,你必须手动加载所有的依赖关系,这也会让人有些沮丧。许多人只是最终在每个请求中加载所有内容,而不管该特定页面实际需要什么。

有很多库试图解决这些问题,并使文件之间的导出和导入功能更易于管理。今天比较常见的一个是RequireJS,它是CommonJS AMD specs的执行。您可以找到其他库和它们之间的比较here,并且有一篇关于如何使用这些库在Addy Osmani blog上编写模块化JavaScript的精彩教程 - 其中还讨论了ES.next中即将推出的新模块系统,这也很有趣。

我个人很喜欢NodeJS's modules system(与exports对象和require功能),所以我用node-browserify将它打包了对客户端的工作压力太大。虽然这不允许像AMD规范那样以异步方式动态加载依赖项,但它确实允许在客户端和服务器端很好地共享相同的JavaScript代码,这对我来说是一个巨大的好处(主要是因为我与服务器端的NodeJS一起工作,所以我不确定这对你有多重要),并且通过解析你的代码,它可以很好地将所有的依赖关系打包在一起(因此它们可以同步到require() d) JavaScript代码并寻找简单的require()调用来确定给定脚本运行所需的内容。

+0

感谢您的回答! – plang 2011-11-29 07:18:55

6

你也可以做这样的:

@app = window.app ? {} 

app.Foo = Foo 

这将使app包含所有全局类和window.app ? {}可以确保您只会造成一个app