为CoffeeScript类创建命名空间
如何为用CoffeeScript编写的类创建名称空间 例如,我有树类Aa、Bb和Cc。我希望它们插入到全局可组装的名称空间-MyClasses,允许跨它们通信并在jasmine节点中使用它们为CoffeeScript类创建命名空间,coffeescript,Coffeescript,如何为用CoffeeScript编写的类创建名称空间 例如,我有树类Aa、Bb和Cc。我希望它们插入到全局可组装的名称空间-MyClasses,允许跨它们通信并在jasmine节点中使用它们 class MyClasses.Aa @someProp: true class MyClasses.Bb @someProp2: false class MyClasses.Cc @doSomeStuff: -> MyClasses.Aa.someProp = false 我知道,我可以
class MyClasses.Aa
@someProp: true
class MyClasses.Bb
@someProp2: false
class MyClasses.Cc
@doSomeStuff: -> MyClasses.Aa.someProp = false
我知道,我可以将它们注入一个文件并进行编译,但我想要一个类=一个文件
请问我怎么做?
谢谢大家!
编辑:我试过这种方法,但我认为它不好,但它在浏览器和jasmine节点中工作
root = exports ? this
root.MyClasses = root.MyClasses ? {}
root.MyClasses.Aa =
class Aa
您可以使用
-b
标志编译CoffeeScript文件,该标志将删除安全包装。或者使用类似于您已经拥有的东西将您的类公开到全局范围
a、 咖啡
b、 咖啡
c、 咖啡
重复其他课程。在第一行中,我发现窗口
比此
更加明确,第二行也允许您只将类附加到MyClasses
,而不需要长序列的名称空间
在浏览器中,您的类将位于全局对象MyClasses
在node.js中,您可以这样使用它们(这有点冗长):
pd:我还没有和node jasmine核对过。使用RequireJS。 在一个名为“my classes.coffee”的文件中,定义名称空间
define [], ->
# You need this if you want it to work in multiple environments.
# Otherwise just use `window` to work in the browser.
root = exports ? this
root.MyClasses = {}
您可以在另一个名为“aa.coffee”的文件中定义类
另一个文件:
define ['my-classes'], (MyClasses) ->
class MyClasses.Bb
@someProp2: false
现在,当您需要时,它应该导出MyClasses
,其中包括MyClasses.Aa
require ['my-classes', 'aa'], (MyClasses, _) ->
console.log MyClasses.Aa.someProp
这样做的一个问题是,您不能只依赖require
语句中的“我的类”。如果这样做,MyClasses.Aa
将是未定义的。但是你也不能仅仅依赖于“aa”,因为“aa”除了通过添加到MyClass之外,不会导出任何东西。在上面的代码片段中,MyClasses.Bb
是未定义的,因为我没有明确依赖它。这就是为什么许多人要么使用一个巨大的文件,要么复制重新导出名称空间的样板文件
define [], ->
# You need this if you want it to work in multiple environments.
# Otherwise just use `window` to work in the browser.
root = exports ? this
root.MyClasses = {}
如果有人知道如何解决这个问题,请告诉我
一、 就个人而言,发现RequireJS使用起来很复杂,有很多不同的方法来设置它。我在jasmine中使用它的一种方法是使用一个蛋糕任务将我的咖啡脚本预编译成JavaScript,然后生成这样的规范文件
requirejs = require('requirejs')
# Set the baseURL to your compiled JS dir.
requirejs.config { baseUrl: __dirname + '/../lib' }
requirejs ['my-classes', 'aa'], (MyClasses, _) ->
describe "someProp", ->
it "should be true", ->
expect(MyClasses.Aa.someProp).toEqual true
这可能不是最好的方法,但我能够使用它在浏览器、节点服务器和jasmine节点测试中运行模块。我还看到一些人在他们的规范文件中避免使用样板文件
如果您不想使用RequireJS,您可能会发现它很有用。它通过使用上定义的
名称空间函数来工作。在Coffescript wiki中有一个建议的解决方案:
发件人:
#代码:
#
名称空间=(目标、名称、块)->
[目标、名称、块]=[(如果导出类型不是“未定义”,则导出其他窗口)、参数…]如果arguments.length<3
顶部=目标
target=target[item]或={}用于name.split.'中的项
顶住目标
#用法:
#
名称空间“Hello.World”(导出)->
#“exports”是附加命名空间成员的位置
exports.hi=->console.log“hi World!”
名称空间“Say.Hello”,(导出,顶部)->
#'top'是对主命名空间的引用
exports.fn=->top.Hello.World.hi()
Say.Hello.fn()打印“嗨,世界!”
为什么不使用requirejs/amd?有没有办法不用重复标题或使用requirejs就可以做到这一点?好的,我会使用requirejs,但是我怎样才能在jasmine节点测试中使用requirejs?用jasmine的例子更新了。我编写了这个测试,但当我开始它时,它会给我结果:在0秒内完成0个测试,0个断言,0失败
请参阅有关的链接。这里也有一些例子。如果你还是不明白,我会问一个新问题。这不再是关于CoffeeScript中的名称空间,而是关于如何运行jasmine节点来测试RequireJS模块。
define ['my-classes'], (MyClasses) ->
class MyClasses.Aa
@someProp: true
define ['my-classes'], (MyClasses) ->
class MyClasses.Bb
@someProp2: false
require ['my-classes', 'aa'], (MyClasses, _) ->
console.log MyClasses.Aa.someProp
requirejs = require('requirejs')
# Set the baseURL to your compiled JS dir.
requirejs.config { baseUrl: __dirname + '/../lib' }
requirejs ['my-classes', 'aa'], (MyClasses, _) ->
describe "someProp", ->
it "should be true", ->
expect(MyClasses.Aa.someProp).toEqual true
# Code:
#
namespace = (target, name, block) ->
[target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
top = target
target = target[item] or= {} for item in name.split '.'
block target, top
# Usage:
#
namespace 'Hello.World', (exports) ->
# `exports` is where you attach namespace members
exports.hi = -> console.log 'Hi World!'
namespace 'Say.Hello', (exports, top) ->
# `top` is a reference to the main namespace
exports.fn = -> top.Hello.World.hi()
Say.Hello.fn() # prints 'Hi World!'