Как написать сухой, модульный coffeescript со звездочками в Rails 3.1?
Я на ранних стадиях пытаюсь написать какой-то разумный 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 ответа:
У меня есть модульное решение, которое я использую в своем коде.
Я определяю свои модули, как показано ниже
@module "foo", -> @module "bar", -> class @Amazing toString: "ain't it"
Amazing доступен как
foo.bar.Amazing
Реализация помощника @module-это
Это написано на сайте coffeescript здесь.window.module = (name, fn)-> if not @[name]? this[name] = {} if not @[name].module? @[name].module = window.module fn.apply(this[name], [])
Https://github.com/jashkenas/coffee-script/wiki/Easy-modules-with-coffeescript
Просто держите module1.js as-is и сделать заявку.js выглядит примерно так:
//= require 'module1' class @MyApp ... @Module1 = Module1
Это будет работать, потому что вы сделали
Module1
глобальным (объявлениеclass @Module1
эквивалентно написанию@Module1 = class Module1
, и@
указывает наwindow
в этом контексте), а в телеclass @MyApp
@
указывает на сам класс.Если вы хотите
Module1
, Чтобы только было свойством глобального классаMyApp
после его присоединения, вы можете добавить строкуdelete window.Module1
Вот модульный шаблон, который я использую для управления coffeescript со звездочками (работает также с Rails 4):
Одним из недостатков этого подхода является то, что вы выставляете свои объекты в окне. Добавление загрузчика модулей или принятие нового синтаксиса es вокруг модулей может быть хорошей альтернативой в зависимости от ваших потребностей.# 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