Как вы пишете СУХОЙ, модульный coffeescript с Sprockets в Rails 3.1? - PullRequest
15 голосов
/ 25 июля 2011

Я нахожусь на ранних стадиях попыток написать какой-нибудь разумный 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()'

Не похоже, что Звездочки могут это сделать.

Есть ли разумный способ требовать, чтобы мои файлы CoffeeScript находились в нужном месте в моих файлах-контейнерах? Или другой подход к написанию модульного кода, который разделен на отдельные файлы с использованием CoffeeScript, Sprockets и Rails 3.1?

Ответы [ 3 ]

4 голосов
/ 25 июля 2011

Просто сохраните module1.js как есть и сделайте application.js похожим на это:

//= require 'module1'

class @MyApp
  ...

  @Module1 = Module1

Это будет работать, потому что вы сделали Module1 глобальным (объявление class @Module1 эквивалентнона запись @Module1 = class Module1, и @ указывает на window в этом контексте), а в теле class @MyApp, @ указывает на сам класс.

Если вы хотите, чтобы Module1 только быть свойством глобального MyApp класса после его присоединения, вы можете добавить строку

delete window.Module1
3 голосов
/ 26 июля 2011

У меня есть модульное решение, которое я использую в своем коде.

Я определяю свои модули, как показано ниже

@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

1 голос
/ 08 сентября 2013

Вот модульный шаблон, который я использую для управления coffeescript со звездочками (также работает с 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 вокруг модулей может быть хорошей альтернативой в зависимости от ваших потребностей.

...