2012-01-04 15 views
14

yo encontramos este fragmento en el CoffeeScript Preguntas para la creación de espacios de nombres simplistas ..Clases dentro de CoffeeScript 'Espacio de nombres'

# Code: 
# 
namespace = (target, name, block) -> 
    [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3 
    top = target 
    target = target[item] or= {} for item in name.split '.' 
    block target, top 

# Usage: 
# 
namespace 'Hello.World', (exports) -> 
    # `exports` is where you attach namespace members 
    exports.hi = -> console.log 'Hi World!' 

namespace 'Say.Hello', (exports, top) -> 
    # `top` is a reference to the main namespace 
    exports.fn = -> top.Hello.World.hi() 

Say.Hello.fn() # prints 'Hi World!' 

Eso es todo muy bien, pero estoy teniendo una gran cantidad de problemas para hacer esto con el class palabra clave. Tal que ...

namespace 'Project.Something', (exports) -> 
    exports.something = -> class something 
    // .. code here 
    exports.somethingElse = class somethingElse extends something 

¿Alguien puede arrojar algo de luz sobre la sintaxis que lograría esto?

Respuesta

19

El truco es crear la primera clase

class MyFirstClass 
    myFunc:() -> 
    console.log 'works' 

class MySecondClass 
    constructor: (@options = {}) -> 
    myFunc:() -> 
    console.log 'works too' 
    console.log @options 

Entonces en algún lugar cerca del final de la exportación de archivos de todas las clases que necesitan ser expuestos.

namespace "Project.Something", (exports) -> 
    exports.MyFirstClass = MyFirstClass 
    exports.MySecondClass = MySecondClass 

Más adelante se puede utilizar las clases como así:

var firstClass = new Project.Something.MyFirstClass() 
firstClass.myFunc() 

var secondClass = new Project.Something.MySecondClass 
    someVar: 'Hello World!' 

secondClass.myFunc() 
+1

¡Ya vamos! Era tan simple, pero tan frustrante al mismo tiempo. ¡Gracias! – Ciel

+0

Debería haber un método que haga esto por usted :( – jackyalcine

+0

¿Esto no derrota el propósito del Espaciado de nombres? ¿Visto como MyFirstClass ahora se define tanto en el Espacio de nombres como fuera de él? @ La respuesta de ChrisSubagio parece una forma más correcta de hacerlo –

24

Aún mejor, la sintaxis de clase permite que el nombre sea realmente en la forma de un elemento, por lo que en realidad se puede simplemente hacer :

namespace 'Secrets', (exports) -> 
    class exports.Hello 
    constructor: -> 
     @message = "Secret Hello!" 

a = new Secrets.Hello 
console.log a.message 

violín completa aquí: http://jsfiddle.net/7Efgd/1/

+1

Esta debería ser la respuesta aceptada. –

+0

Esto es una solución válida también. Es realmente una cuestión de preferencia. Para mí, el ejemplo anterior es un poco más fácil de entender. ¡ – Sandro

+0

debe tenerlo! ¡Está funcionando! –

1

Cómo sobre el uso someth ing como esto?

module = 
    Hello: class Hello extends Backbone.Model 
     constructor: -> 
      @message = 'Hello' 

    Hello2: class Hello2 extends Backbone.View 
     constructor: -> 
      @message = 'Hello2' 
Cuestiones relacionadas