Как писать сухой модульный кофериплет с звездочками в рельсах 3.1?
Вопрос
Я на ранних стадиях попытки написать какой -нибудь разумный JavaScript. Я хочу, чтобы пространство имен, в основном, все под названием моего приложения, чтобы как можно больше глобальности, но все же дал мне возможность получить доступ к функциям, объявленным по месту места. Тем не менее, я не хочу быть очень многословным в определениях моих функций.
Мой идеальный коферипп был бы что -то в этом роде:
class @MyApp
@myClassMethod = ->
console.log 'This is MyApp.myClassMethod()'
class @Module1
@moduleMethod = ->
console.log 'This is MyApp.Module1.moduleMethod()'
Вы получаете картинку. Таким образом, я избегаю писать MyApp.Module.submoduleMethod = ->
Каждый раз, когда я хочу правильно определить функцию с именами, используя @
и определение вещей в пределах Мое определение класса делает все красивым и коротким.
Все идет хорошо, пока я не хочу разделить свою функциональность на несколько файлов кофериста. Тогда я действительно хочу что -то вроде этого:
// application.js
class @MyApp
//= require 'module1'
//= require 'module2'
// module1.js
class @Module1
@moduleMethod = ->
console.log 'This is STILL MyApp.Module1.moduleMethod()'
Это не похоже на то, что звездочки могут сделать это.
Есть ли разумный способ потребовать мои файлы CoffeeScript в нужном месте в моих файлах контейнеров? Или еще один способ обратиться к написанию модульного кода, который разделен на отдельные файлы с использованием кофериста, звездочек и рельсов 3.1?
Решение
У меня есть модульное решение, которое я использую в своем коде.
Я определяю свои модули, как ниже
@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
Другие советы
Просто сохраните module1.js как есть и заставьте применение. JS выглядеть примерно так:
//= require 'module1'
class @MyApp
...
@Module1 = Module1
Это будет работать, потому что вы сделали Module1
глобальный (объявление class @Module1
эквивалентен письму @Module1 = class Module1
, а также @
указывает на window
в этом контексте) и в class @MyApp
тело, @
указывает на сам класс.
Если хочешь Module1
к Только быть собственностью глобального MyApp
класс после его прикрепления, вы можете добавить линию
delete window.Module1
Вот модульный рисунок, который я использую для управления кофейсом с помощью 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 вокруг модулей может быть хорошей альтернативой в зависимости от ваших потребностей.