2012-01-04 3 views
14

Я нашел этот фрагмент кода на CoffeeScript FAQ для создания упрощенных пространств имен ..Классы в пределах CoffeeScript «Пространство имен»

# 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!' 

То есть все хорошо, но я имею много хлопот делать это с class ключевое слово. Такие, что ..

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

Может ли кто-нибудь пролить свет на синтаксис, который бы это сделал?

ответ

19

Хитрость заключается в том, чтобы создать класс первого

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

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

Тогда где-то ближе к концу файла экспорт всем классов, чем необходимость быть открытыми.

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

Позже вы можете использовать классы, как так:

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

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

secondClass.myFunc() 
+1

Там мы идем! Это было так просто, но так расстраивало в то же время. Спасибо! – Ciel

+0

Должен быть метод, который сделает это за вас :( – jackyalcine

+0

Не побеждает ли цель Namespacing? Видите, как MyFirstClass теперь определен как в пространстве имен, так и вне его? @ Ответ ChrisSubagio кажется более правильным способом сделать это –

24

Даже лучше, синтаксис класса позволяет имя на самом деле быть в форме члена, так что вы на самом деле можете просто сделать :

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

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

Полная скрипку здесь: http://jsfiddle.net/7Efgd/1/

+1

Это должен быть принятый ответ. –

+0

Это Я считаю, что пример выше немного легче для меня понять. – Sandro

+0

должен быть! Это работает! –

1

Как об использовании someth как это?

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

    Hello2: class Hello2 extends Backbone.View 
     constructor: -> 
      @message = 'Hello2' 
Смежные вопросы