骨干双重发布问题

时间:2013-12-04 20:45:11

标签: backbone.js

我有一个奇怪的Backbone问题,可能与骨干的工作方式有关,我还不明白。

我有一个带有按钮的主屏幕,可以转到其他路线。如果我点击一个然后去那条路线一切正常。如果我返回菜单并单击相同的路线,则每次点击事件都会运行两次。如果我再次这样做,每次点击事件都会运行三次......等等

为什么会这样?我错过了什么?

菜单页面链接:

<a class="btn btn-large homebutton" id="addcrateslink" data-href="/#/crateadd">Add Crates To New Location</a>

发生这种情况的事件:

    events: {
        "click .homebutton":"redirect"
    },

    redirect: function(e) {
        e.preventDefault();
        // Get details
        var href = $(e.currentTarget).data("href");
        console.log("Href", href);
        Backbone.history.navigate(href.replace("#",""));
    },

路由器如何操作:

    addcrate: function (eventname) {
        var self = this;
        this.showLoading();
        $("#contentitems").html(" ");
        this.ensureLogin(function(){
            if (self.crateCollection.length > 0 && self.crateCollection !== null)
            {
                var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
                addCrateView.on('render', self.hideLoading());
            }
            else
            {
                //Set Up Sort
                self.fetchCrates(function (){
                    console.log("in the fetchcratescallback");
                    var addCrateView = new AddCrateView({model: self.crateCollection, unused: self.unusedCrateCollection, eventtype: eventname });
                    addCrateView.on('render', self.hideLoading());
                });
            }

        });
    },

查看路线上的负载:

var AddCrateView = Backbone.View.extend({
    template: _.template(AddCrateTemplate),
    el: "#contentitems",
    utils: new Utils(),
    model: new CrateCollection(),

    initialize: function (models) {
        this.location = models.thelocation;
        if (this.location === null || typeof this.location === "undefined")
        {
            this.location = this.utils.readCookie("location");
        }
        this.destination = this.utils.readCookie("destination");
        this.eventtype = models.eventtype;
        this.crate = models.thecrate;
        this.crateCollection = models.model;
        this.unusedCrates = models.unused;
        this.locationCollection = new LocationCollection();            
        var me = this;
        this.locationCollection.fetch({
            success: function () {
                me.render();
                me.on("render", me.utils.showHideContent());            
            },
            error: function () {
                me.utils.sendAlert("Uh-Oh!", "There was an error loading this page.  Please hit refresh (F5 or CTRL-R).", "error", function(){});
            },
        });
    },

    events: {
        "click #addnewcrate": "createCrate",
        "click #clearlocation": "clearlocation",
        "click #cleardestination": "cleardestination",
        "click #cratelocationscanlink": "locationscan",
        "click #cratescanlink": "cratescan",
        "click #cratedestinationscanlink": "destinationscan",
    },

    showLoading: function () {
        ...
    },

    hideLoading: function () {
        ...
    },

    createCrate: function (eventname) {
        ...
    },

    validateForm: function (currentCrate, unusedCrate) {
        ...
    },

    render: function () {
        var self = this;
        $(this.el).html(this.template({url: this.utils.getDomain() }));

        var typeaheadLocation = new TypeaheadLocation({ collection: this.locationCollection, key: 'Name' });
        typeaheadLocation.setElement('#locationtaholder').render();

        var typeaheadDestination = new TypeaheadDestination({ collection: this.locationCollection, key: 'Name' });
        typeaheadDestination.setElement('#destinationtaholder').render();

        if (typeof this.location !== "undefined" && this.location !== "") {

            var setLocation = this.locationCollection.findWhere({ Name: this.location });

            if (typeof setLocation !== 'undefined') {
                $("#cratescanfalselink").addClass("item-hidden");
                $("#cratescanlink").removeClass("item-hidden");

                $('#location').val(setLocation.get("Name"));
                $('#clearlocation').removeClass("item-hidden");

                if (typeof this.crate !== "undefined") {
                    // Send the crate to the DB
                    $('#name').val(this.crate);
                    self.createCrate();
                }
            }
            else
            {
                self.utils.sendAlert("Location Error!", "Error setting location: It appears that this location does not exist in the system.", "error", function(){});
            }
        }

        // Set destination
        if (typeof self.destination !== "undefined" && self.destination !== "") {

            var setDestination = self.locationCollection.findWhere({ Name: self.destination });

            if (typeof setDestination !== 'undefined') {
                $('#destination').val(setDestination.get("Name"));
                $('#cleardestination').removeClass("item-hidden");
            }
            else
            {
                console.log("In wrong destination catch...");
                self.utils.sendAlert("Location Error!", "Error setting destination: It appears that this destination does not exist in the system.", "error", function(){});
            }
        }

        this.testtype();
    },

    showRemainingCrates: function(currentLocation, newlocation){
        ...
    },

    clearlocation: function () {
        ...
    },     

    cleardestination: function () {
        ...
    },

    testtype: function() {
        ...
    },

    locationscan: function (e) {
       ...          
    },

    destinationscan: function (e) {
       ...           
    },

    cratescan: function (e) {
       ...          
    }

});

1 个答案:

答案 0 :(得分:1)

听起来你可能有僵尸视图问题。您的旧观点可能没有被清理。

一种策略是在路由器中创建一个包含对当前视图的引用的变量。在加载另一个视图之前,请检查该变量是否在其中包含视图,如果有,则在添加新视图之前在其上call remove

这应该完全从DOM中删除它,并取消绑定任何事件。

if (currentView && 'remove' in currentView) {
  currentView.remove();
}