15

我正处于尝试编写一些明智的 Javascript 的早期阶段。我想基本上以我的应用程序名称命名所有内容,以尽可能避免全局变量,但仍然给我一种访问在该位置周围声明的函数的方法。但是,我不想在函数定义中过于冗长。

我理想的 CoffeeScript 应该是这样的:

class @MyApp
  @myClassMethod = ->
    console.log 'This is MyApp.myClassMethod()'

  class @Module1
    @moduleMethod = ->
      console.log 'This is MyApp.Module1.moduleMethod()'

你得到图片。这样我就避免了MyApp.Module.submoduleMethod = ->每次我想正确定义命名空间函数时都必须编写 -@我的类定义中使用和定义事物可以使事情变得简洁明了。

这一切都很顺利,直到我想将我的功能拆分为多个 CoffeeScript 文件。那么我真正想要的是这样的:

// application.js
class @MyApp
  //= require 'module1'
  //= require 'module2'

// module1.js
class @Module1
  @moduleMethod = ->
    console.log 'This is STILL MyApp.Module1.moduleMethod()'

Sprockets 似乎无法做到这一点。

有没有一种明智的方法来要求我的 CoffeeScript 文件在我的容器文件中的正确位置?或者使用 CoffeeScript、Sprockets 和 Rails 3.1 编写模块化代码的另一种方法?

4

3 回答 3

4

只需保持 module1.js 原样并使 application.js 看起来像这样:

//= require 'module1'

class @MyApp
  ...

  @Module1 = Module1

这将起作用,因为您已经创建了Module1一个全局(声明class @Module1等同于写作@Module1 = class Module1,并在该上下文中@指向window),并且在class @MyApp正文中,@指向类本身。

如果您只想Module1在附加后成为全局类的属性,则可以添加MyApp

delete window.Module1
于 2011-07-25T14:24:12.897 回答
3

我有一个在我的代码中使用的模块解决方案。

我定义我的模块如下

@module "foo", ->
    @module "bar", ->
        class @Amazing
            toString: "ain't it"

惊人的可作为

foo.bar.Amazing

@module 助手的实现是

window.module = (name, fn)->
  if not @[name]?
    this[name] = {}
  if not @[name].module?
    @[name].module = window.module
  fn.apply(this[name], [])

它写在coffeescript网站上。

https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript

于 2011-07-26T06:47:30.533 回答
1

这是我用于使用 sprockets 管理咖啡脚本的模块化模式(也适用于 Rails 4):

  # utils.js.coffee

  class Utils
    constructor: ->

    foo: ->
      alert('bar!!!')

    # private methods should be prefixed with an underscore
    _privateFoo: ->
      alert('private methods should not be exposed')

  instance = new Utils()

  # only expose the methods you need to.
  # because this is outside of the class,
  # you can use coffee's sugar to define on window

  @utils = foo: instance.foo

  # otherscript.js.coffee 

  //= require utils
  class OtherScript
    constructor: ->
      @utils.foo()         # alerts bar!!!
      @utils._privateFoo() # undefined method error

这种方法的一个缺点是您将对象暴露在窗口上。根据您的需要,添加模块加载器或在模块周围采用一些新的 es 语法可能是一个不错的选择。

于 2013-09-08T19:02:04.477 回答