2014-03-12 35 views
1

我正在使用jQuery在多個javascript對象之間分派事件。jQuery未能在一個coffeescript構造函數中調用時附加一個事件處理程序

我有一個CoffeeScript的類,即附加一個自定義事件處理程序,以在其構造的對象:

class Player 

    constructor: -> 
    @queue = new MediaQueue() # custom queue class 
    $(@queue).on 'purged', (event, purged) => 
     media.destroy() for media in purged 
     @fillQueue() 

我的問題是,這個處理程序不會被調用。

此外,內部鍍鉻的控制檯,當我嘗試:

$._data(player.queue, 'events') 

我得到undefined

奇怪的部分是,將該處理程序附加到構造函數外的任何位置都可以工作。

$(player.queue).on('purged', function(event, purged){ 
    console.log('purged',purged) 
}); 
player.queue.purge(); 

=> purged, > Array[2] 

它即使結合邏輯構造之後調用工作:

class Player 

    constructor: -> 
    @queue = new MediaQueue() 

    bindQueue: -> 
    $(@queue).on 'purged', (event, purged) => 
     media.destroy() for media in purged 
     @fillQueue() 

則:

var player = new Player(); 
player.bindQueue() 
player.queue.purge() # the handler gets called as it should 

我懷疑在Chrome控制檯

仍一個可變範圍問題。爲什麼我不能在構造函數中附加這個處理程序?

UPDATE

我發現了一個奇怪的解決方法。

這裏是我如何實例化球員:

$(document).ready -> 
    $('[data-somenamespace-player]').each -> 
    # the player is actually bound to a container 
    # I just shortened the constructor code for simplicity's sake 
    @somenamespace_player = new Player(@) 

如果我嘗試這樣的處理程序綁定,這是行不通的:

$(document).ready -> 
    $('[data-somenamespace-player]').each -> 
    @somenamespacePlayer = new Player(@) 
    $(@somenamespacePlayer.queue).on 'purged', (event, purged) => 
     media.destroy() for media in purged 
     @somenamespacePlayer.fillQueue() 

...但它確實工作當我使用超時:

$(document).ready -> 
    $('[data-somenamespace-player]').each -> 
    @somenamespacePlayer = new Player(@) 
    setTimeout => 
       $(@somenamespacePlayer.queue).on 'purged', (event, purged) => 
        media.destroy() for media in purged 
        @somenamespacePlayer.fillQueue() 
       , 
       5000 

怎麼會這樣?它可能是相對於我的Queue類的東西嗎?

UPDATE

有一些奇怪的是,我在調試器發現。我設置了構造函數中的斷點,然後嘗試這樣:

$(this) 
=> [] 

我還設置一個斷點裏面一個是使用第一隊列的方法,同樣的協議:

$(this) 
=> [] 

然後,恢復執行後等待了一下:

$(player.queue) 
=> [>MediaQueue] 

而且,當MediaQueue構造函數中,我注意到一個奇怪的行爲(實際編譯JS):

function MediaQueue() { 
     var _this = this; // if I try $(this) in the console at this stage, i get 
         // a TypeError : cannot read property length of undefined 

     this._medias = [];  // idem at this stage, just before assignment 
     this._currentIndex = 0; // now $(this) => [] 
} 

我懷疑的東西是對持續超出了我如何JavaScript的作品的理解......

+0

您是否查看過CoffeeScript編譯器的輸出,即編譯器生成的實際JavaScript? – Jonathan

+0

@Jonathan是的,這裏沒什麼奇怪的 –

+0

@mu不,這是一個錯字,我會解決它。這不是實際的代碼,我縮短了它。 –

回答

1

所以它似乎我犯了一個愚蠢的錯誤......

正因爲如此:

class MediaQueue 

    Object.defineProperties @prototype, 
          length: -> @_medias.length 

jQuery是無法將事件處理程序附加到MediaQueue對象當隊列爲空(這也解釋了setTimeout解決方法)。

我不知道爲什麼,但它肯定不是很聰明的在第一時間創建這樣的屬性...

編輯:原因是$。每個與考慮的長度對象財產迭代,並試圖附加處理的對象,而不是對象本身的每個屬性...

綜上所述:當你想在觸發事件沒有創建對象length屬性他們與jQuery。

編輯

看來,我不是一個人硬着頭皮 - 對jQuery的Bug跟蹤某人filed this as an issue,只看到它封閉的原因不是一個錯誤 - 這是爲了$的行爲。每個

相關問題