2013-05-08 34 views
1

我是JavaScript和Backbone的新手,我遇到了這個錯誤。Backbone.js - 無法觸發集合中的事件

Router = Backbone.Router.extend({ 

    routes: { 
     ":albumID": "load" 

    }, 

    load: function (albumID) { 
     if (controller.collectionInitialized == true) { 
      console.log("RESET"); 
      album.trigger("clear"); 
     } 

     var album = new Album([], { 
      title: albumID 
     }); 

     controller.trigger("collectionInit"); 
     controller.trigger("switchAlbum", albumID); 
    } 
}); 

Controller = Backbone.Model.extend({ 

    currentAlbum: "", 
    collectionInitialized: false, 

    initialize: function() { 
     console.log("controller is initialized"); 
     this.on("switchAlbum", function (newAlbum) { 
      this.currentAlbum = newAlbum; 

     }); 

     this.on("collectionInit", function() { 
      this.collectionInitialized = true; 
     }); 
    } 
}); 

Album = Backbone.Collection.extend({ 

    initialize: function (models, options) { 
     this.on("clear", this.clear); 
    }, 
    clear: function() { 
     this.reset(); 
     this.off(); 
    } 

}); 

我收到此錯誤:Unable to get property 'trigger' of undefined or null reference。在觸發clear之前,if聲明確保album已經存在。之前我嘗試直接撥打album.reset(),但得到相同的錯誤。我的猜測是這是某種範圍的問題,有人可以請我指出正確的方向嗎?

回答

1

EDIT

重新讀代碼,假設controller是一個有效的實例並且存在,並且假定controller.collectionInitialized設置爲true,則基本上調用方法trigger上的變量album,其值爲空。

使用JS提升規則,你的負載功能可能已經被寫成

load: function(albumID) { 

    var album = null; 

    if (controller.collectionInitialized == true) { 
     console.log("RESET"); 
     album.trigger("clear"); 
    } 

    album = new Album([], { title: albumID }); 
    controller.trigger("collectionInit"); 
    controller.trigger("switchAlbum", albumID); 
} 

也許,上述重新寫清楚地表明,即使controller.collectionInitializedtruealbum是一個局部變量,將始終被重置每次調用加載函數時都爲null。

你曾經使用過什麼機制來啓用對controller的全局訪問,使用相同的方法來啓用全局訪問album。不要將album重新聲明爲本地函數。

...

它可以幫助閱讀更多關於Javascript variable and function hoisting

1

的確,在Javascript中,變量是function-scoped,這意味着它們在本地範圍內(即函數主機)是可見的,但實例化是不同的野獸。

load: function (albumID) { 

    if (controller.collectionInitialized == true) { 
     console.log("RESET"); 
     album.trigger("clear"); 
    } 

    var album = new Album([], { 
     title: albumID 
    }); 

    controller.trigger("collectionInit"); 
    controller.trigger("switchAlbum", albumID); 
} 

您創建一個new Album你打電話專輯方法trigger,從而導致空引用。

而且,即使你調用該函數的兩倍(即具有controller.collectionInitializedfalse,而第二次作爲true第一次),自變量album是本地的,當你進入if體,它總是不確定的功能,因爲它的範圍是功能load,所以它每次到達load的身體時都會「死亡」。

Amith George提供正確的解決問題的方法:定義變量album在一個範圍更高的水平(即,對象的傳遞作爲參數傳遞給extend方法的水平)

+0

但是,如果'專輯'已經被創建,if語句確保它只觸發'clear'。這不重要嗎? – Dmitry 2013-05-08 16:38:42

+0

@DimaShabatin實際上,我根據我對Javascript的瞭解(我不曾碰巧使用過Backbone)。你在哪裏定義'collectionInit'和'collectionInitialized'? – 2013-05-08 16:48:58

+0

只需在帖子中添加更多代碼即可 – Dmitry 2013-05-08 17:13:14