2014-01-07 53 views
1

中訪問Coffeescript中的實例屬性,所以我在節點應用程序中使用express。隨着我的應用程序越來越大,我想將我的路線放到額外的文件中。我似乎能夠抓住bugDB,如果我剛剛擺脫中間獲取對象。但是我無法訪問內部對象中的bugDB。有什麼建議麼?也許還有更好的代碼模式可以更好地完成這個任務。在嵌套的

我會appreachate你的幫助。提前致謝。 (由於我不是母語的人我無法找到其他類似的問題,如果你知道如何詞組這個問題比較好,請告訴我的方式:))

BUGROUTER.COFFEE 
class BugsRouter 
    constructor: (@bugDB)-> // instance-variable with databaselink 
     return 

    get:{ 
     allBugs: (req, res)=> 
      console.log "db", @bugDB // this gives me undefined 
            // is "this" in the get context? 
      @bugDB.allDocs {include_docs: true}, (err, response)-> 
       res.json 200, response 
     } 
module.exports = BugsRouter 

SERVER.COFFEE 
BugsRouter = require "./routes/BUGROUTER" 
bugsRouter = new BugsRouter(bugDB) 
console.log bugsRouter.bugDB # this is working 
app.get "/bugs/all", bugsRouter.get.allBugs 

回答

0

嗯,看來我找到了一個更好的解決方案畢竟:

class Test 
    constructor: -> 
     @testVariable = "Have a nice" 
     return 

    Object.defineProperties @prototype, 
     get: 
      enumerable :true 
      get:-> 
       { 
        day: => @testVariable + " day" 
        week: => @testVariable + " day" 
       } 

console.log (new Test()).get.day() 

這允許我以我想要的方式致電(new Test()).get.day()。 現場版:JSFiddle

2

子對象不像那樣工作。當你這樣說:

class C 
    p: 
     f: -> 

然後p只是一個簡單的對象恰好是C的原型的屬性,它會有什麼樣@應該是內部f沒有特別的想法。如果你嘗試使用,而不是脂肪的箭頭:

class C 
    p: 
     f: => 

那麼你不小心創建一個名爲f所以@Cf被稱爲命名空間類的函數。無論是哪種情況,他說:

c = new C 
c.p.f() 

是一樣的:

c = new C 
p = c.p 
p.f() 

所以f將在p而非c上下文中調用。

可以解決這個問題,如果你不介意手動綁定內get的功能,當你constructor叫做:

constructor: (@bugDB) -> 
    @get = { } 
    for name, func of @constructor::get 
     @get[name] = func.bind(@) 

這是假設你有Function.bind可用。如果您不這樣做,則可以使用其他任何綁定技術(_.bind,$.proxy,...)。需要@get = { }技巧以確保您不會意外修改原型的@get版本;如果您確信您只需要創建BugsRouter的一個實例,那麼你可以使用它代替:

constructor: (@bugDB) -> 
    for name, func of @get 
     @get[name] = func.bind(@) 

綁定原型的版本get內部的功能,而不是實例的本地副本。

你可以看這個簡化的演示,看看發生了什麼事情,在不同的情況下@,保持對@flag值的眼睛看到引起不使用@get = { }@constructor::get意外原型修改:

class C1 
    get: 
     f: -> console.log('C1', @) 

class C2 
    get: 
     f: => console.log('C2', @) 

class C3 
    constructor: -> 
     @flag = Math.random() 
     for name, func of @get 
      @get[name] = func.bind(@) 
    get: 
     f: -> console.log('C3', @) 

class C4 
    constructor: -> 
     @flag = Math.random() 
     @get = { } 
     for name, func of @constructor::get 
      @get[name] = func.bind(@) 
    get: 
     f: -> console.log('C4', @) 

for klass in [C1, C2, C3, C3, C4, C4] 
    o = new klass 
    o.get.f() 

直播以上的版本:http://jsfiddle.net/ambiguous/8XR7Z/

+0

由於我不能upvote(儘快我會做):* thumbsup *謝謝你這個徹底的解釋!這對我有很大的幫助。 – Dom

+0

那麼你會建議儘可能避免子對象?我喜歡他們的模塊化 – Gundon

+0

@Gundon你可以使用它們,如果你想,但你必須手動綁定他們的地方,你需要記住綁定他們不是免費的。只是通常的權衡問題。 –