2
votes

I got this weird thing yesterday. I try several of time to fix this problem. When I came back the page same twice, my app trigger alert multiple times, depends how many times I visit the page. I already done some research regarding to this 'zombie' thing and memory lack through this site and internet, but I found dead end. It's already 2 days can't fix this issue.

My code

View page

initialize: function() {
    $(window).scroll(function() {
        if ($(window).scrollTop() + $(window).height() == $(document).height()) {
            alert("bottom!");
        }
    });
    this.bind("reset", this.updateView());
},
render: function() {
    this.$el.html(notificationListViewTemplate);
},
updateView: function() {
    console.log("clear");
    this.remove();
    this.render();
}

router

showNotificationList: function(actions) {
    var notificationListView = new NotificationListView();
    this.changePage(notificationListView);
},

Why it happen?

1

1 Answers

1
votes

Calling View.remove will indeed undelegate events set by the view

remove view.remove()
Removes a view from the DOM, and calls stopListening to remove any bound events that the view has listenTo'd.

but it can only do so on the events it know about : the ones set by the events hash or by calling this.listenTo

You set up a scroll listener but you never remove it, which means the past views will keep listening : see this demo of your predicament http://jsfiddle.net/nikoshr/E6MQ6/

In this case, you can't use the hash of events so you have to take care of the cleaning up yourself, for example by overriding the remove method :

var V = Backbone.View.extend({
    initialize: function() {
        $(window).scroll(function() {
        if ($(window).scrollTop() + $(window).height() == $(document).height()) {
            console.log("bottom!");
        }
        });
    },
    render: function() {
    },
    updateView: function() {
        console.log("clear");
        this.remove();
        this.render();
    },
    remove: function() {
        Backbone.View.prototype.remove.call(this);
        $(window).off('scroll'); // for example, will remove all listeners of the scroll event
    }
});

And a demo http://jsfiddle.net/nikoshr/E6MQ6/1/

And a slightly less brutal removing of the scroll event, by using a namespaced listener :

var V = Backbone.View.extend({
    initialize: function() {
        $(window).on('scroll.'+this.cid, function() {
            ...
        });
    },
    remove: function() {
        Backbone.View.prototype.remove.call(this);
        $(window).off('scroll.'+this.cid);
    }
});

http://jsfiddle.net/nikoshr/E6MQ6/2/