2013-05-08 50 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

相关问题