Wie schreiben Sie TROCKEN, modular coffeescript mit Ritzel in Rails 3.1?
Frage
Ich bin in den frühen Stadien zu schreiben versucht, einige vernünftige Javascript.Ich möchte namespace im Grunde alles, was unter dem Namen meiner Anwendung zu vermeiden, globals, so viel wie möglich, aber noch geben Sie mir eine Möglichkeit zum Zugriff auf Funktionen deklariert rund um den Ort.Aber ich will nicht super ausführlich in meiner Funktion Definitionen.
Meine ideale CoffeeScript würde etwas wie dieses:
class @MyApp
@myClassMethod = ->
console.log 'This is MyApp.myClassMethod()'
class @Module1
@moduleMethod = ->
console.log 'This is MyApp.Module1.moduleMethod()'
Sie erhalten das Bild.Auf die Weise kann ich vermeiden, dass zu schreiben MyApp.Module.submoduleMethod = ->
jedes mal, wenn ich wollen zu definieren Namespaces einwandfrei mit @
und der Definition der Dinge innerhalb meine Klasse definition hält die Dinge schön und kurz.
Dieses ist alles gut, bis ich mir Spalten wollen meine Funktionalität in mehreren CoffeeScript-Dateien.Dann, was ich wirklich will, ist etwas wie dieses:
// application.js
class @MyApp
//= require 'module1'
//= require 'module2'
// module1.js
class @Module1
@moduleMethod = ->
console.log 'This is STILL MyApp.Module1.moduleMethod()'
Es scheint nicht, wie Ritzel kann dies tun.
Gibt es eine vernünftige Art und Weise zu verlangen mein CoffeeScript-Dateien in den richtigen Platz in meinem container-Dateien?Oder auf andere Weise zu nähern, schreiben Sie modularen code, die ist unterteilt in separate Dateien mit CoffeeScript, Ritzel und Rails 3.1?
Lösung
Ich habe eine Modullösung, die ich in meinem Code verwende.
Ich definiere meine Module wie unten
@module "foo", ->
@module "bar", ->
class @Amazing
toString: "ain't it"
Erstaunlich ist als erhältlich als
foo.bar.Amazing
Implementierung des @module Helper ist
window.module = (name, fn)->
if not @[name]?
this[name] = {}
if not @[name].module?
@[name].module = window.module
fn.apply(this[name], [])
Es wird hier auf der CoffeeScript -Website geschrieben.
https://github.com/jashkenas/coffee-script/wiki/easy-modules-with-coffeescript
Andere Tipps
Einfach zu halten module1.js und machen application.js Aussehen etwas wie diese:
//= require 'module1'
class @MyApp
...
@Module1 = Module1
Dies wird funktionieren, weil du das gemacht hast Module1
global (Deklaration class @Module1
ist äquivalent zu schreiben @Module1 = class Module1
, und @
Punkte window
in diesem Kontext), und innerhalb der class @MyApp
Körper, @
Punkte auf die Klasse selbst.
Wenn Sie möchten, Module1
zu nur eine Eigenschaft der globalen MyApp
Klasse nach es ist angebracht, Sie könnte fügen Sie die Zeile
delete window.Module1
Hier ist das modulare Muster, das ich zum Verwalten von Coffeescript mit Kettenrädern verwende (funktioniert auch mit 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
Ein Nachteil dieses Ansatzes ist, dass Sie Ihre Objekte im Fenster freilegen. Das Hinzufügen eines Modulladers oder die Übernahme einiger neuer ES -Syntax um Module kann je nach Ihren Anforderungen eine schöne Alternative sein.