Question

Je suis dans les premiers stades d'essayer d'écrire un peu Javascript sensible. Je veux namespace essentiellement tout sous le nom de ma demande à globals éviter autant que possible, mais encore me donner un moyen d'accéder aux fonctions déclarées autour de la place. Cependant, je ne veux pas être super bavard dans mes définitions de fonction.

Mon idéal CoffeeScript serait quelque chose comme ceci:

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

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

Vous obtenez l'image. De cette façon, j'évite d'avoir à écrire MyApp.Module.submoduleMethod = -> chaque fois que je veux définir une fonction bien des espaces de noms - en utilisant @ et définir les choses dans les ma définition de classe et conserve de belles choses à court

.

Ceci est tout va bien jusqu'à ce que je veux partager mon fonctionnalité en de multiples fichiers CoffeeScript. Alors ce que je veux vraiment quelque chose comme ceci:

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

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

Il ne semble pas Pignons peut le faire.

Y at-il une façon raisonnable d'exiger mes fichiers CoffeeScript au bon endroit dans mes dossiers de conteneurs? Ou une autre façon d'aborder l'écriture de code modulaire qui est divisé en plusieurs fichiers séparés en utilisant CoffeeScript, Pignons et Rails 3.1?

Était-ce utile?

La solution

I have a module solution that I use in my code.

I define my modules like below

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

Amazing is available as

foo.bar.Amazing

implementation of the @module helper is

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

It's written up on the coffeescript website here.

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

Autres conseils

Simply keep module1.js as-is and make application.js look something like this:

//= require 'module1'

class @MyApp
  ...

  @Module1 = Module1

This will work because you've made Module1 a global (declaring class @Module1 is equivalent to writing @Module1 = class Module1, and @ points to window in that context), and within the class @MyApp body, @ points to the class itself.

If you want Module1 to only be a property of the global MyApp class after it's attached, you could add the line

delete window.Module1

Here's the modular pattern I use for managing coffeescript with sprockets (works with Rails 4 as well):

  # 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

One disadavantage of this approach is that you are exposing your objects on window. Adding a module loader or adopting some of the new es syntax around modules could be a nice alternative depending on your needs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top