簡體   English   中英

Backbone.js-無法觸發集合中的事件

[英]Backbone.js - Not able to trigger an event in a collection

我對JavaScript和Backbone相當陌生,遇到了此錯誤。

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 if語句可確保在觸發clear之前該album已經存在。 以前,我嘗試僅直接調用album.reset() ,但遇到相同的錯誤。 我的猜測是這是一種范圍界定問題,有人可以指出正確的方向嗎?

的確,在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 創建一個new Album ,從而導致空引用。

同樣,即使您兩次調用該函數(即,第一次將controller.collectionInitializedfalse ,第二次將其設置為true ),由於變量album在該函數中是局部的,因此在您輸入if主體時也始終是未定義的,因為作用域是函數load ,因此每次到達load主體的末尾時它都會“ 死亡 ”。

Amith George為您的問題提供了正確的解決方案:在更高的作用域級別(即,您作為extend方法的參數傳遞的對象的級別)定義變量album

編輯

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

使用JS提升規則,您的load函數可能被編寫為

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也是一個局部變量,並且每次調用load函數時始終將其重置為null。

使用哪種機制啟用對controller全局訪問權限,都使用相同的方法來啟用對album全局訪問權限。 不要將album重新聲明為該功能的本地album

...

可能有助於閱讀更多有關Javascript變量和函數提升的信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM