How to unbind all the socket.io events from my backbone view?

I have a page which include two backbone views (views related to two template). I am changing content of one views based on clicking event on different items on another view. For this, Every time I click on any items in one view I just create a instance of another view which include some socket.io events. At the first time It's work well but everytime I click on item on first view it just create the instance of 2nd one so that all the socket.io events is binding. Except first click every time I click on items on first view and call an socket.io events, it fired more than one time based on how many click I have done to different items.

I know that every time I click an items it create an instance of a view with socket.io event bind. But I can not get the way to unbind the previous socket.io events.

I have tried to use this reference: Backbone.js View removing and unbinding But it is not working in my case. May be I did not use it in proper way.

Can anyone please give me a solution or way to unbind all the socket.io events binded before?

Here is my Clicking event from where I am creating a new instance of another view where all the socket.io events binds.

 LoadQueueDetails: function (e) {
    e.preventDefault();
    var queues = new Queues();

    queues.fetch({
        data: $.param({ Code: this.model.get("QueueCode") }),
        success: function () {
            $("#grid21").html(new SearchResultListView({ collection: queues }).el);
        },
        error: function (queues) {
            alert('error found in fetch queue details');
        }
    });
   }

And here is my actual view where I bind all the socket.io events.

window.SearchResultListView = Backbone.View.extend({

initialize: function () {
    this.collection.on('change', this.render, this);
    this.render();
},

render: function () {
    var Queues = this.collection;
    var len = Queues.length;

    $(this.el).html(this.template());

    for (var i = 0; i < len; i++) {
        $('.QueueListItem', this.el).append(new SearchResultListItemView({ model: Queues.models[i]}).render().el);
    }
    return this;
 }
});


window.SearchResultListItemView = MainView.extend({
tagName: "tr",

initialize: function () {

    this.__initialize();

    var user;
    if ($.super_cookie().check("user_cookie")) {
        this.user = $.super_cookie().read_JSON("user_cookie");
    }     

    this.model.bind("change", this.render, this);
    this.model.on("destroy", this.close, this);
    socket.emit('adduser', this.user.UserName, this.model.get("Code"));
},

events: {
    "click a": "JoinQueue"
},

onClose: function(){
    this.model.unbind("change", this.render);
},
close: function () {
    this.remove();
    this.unbind();
    this.model.unbind("change", this.render);
},
socket_events: {
    "updatechat": "updatechat",
    "changeroom": "changedroom"
},
changedroom: function (username, data) {
    alert(data);
    socket.emit('switchRoom', data);
},

updatechat: function (username, data) {
    alert(username);
    alert(data);
},

JoinQueue: function (e) {
    e.preventDefault();

    if ($.super_cookie().check("user_cookie")) {
        user = $.super_cookie().read_JSON("user_cookie");
    }

    socket.emit('sendchat', "new user");
},

render: function () {
    var data = this.model.toJSON();
    _.extend(data, this.attributes);
    $(this.el).html(this.template(data));
    return this;
}
});


window.Queue = Backbone.Model.extend({

urlRoot: "/queue",
initialize: function () {
},

defaults: {
    _id:null,
    Code: null,
    ServiceEntityId: null,
    ServiceEntityName:null,
    Name: null,
    NoOfWaiting: null,
    ExpectedTimeOfService: null,
    Status: null,
    SmsCode: null
}

});

window.Queues = Backbone.Collection.extend({
model: Queue,
url: "/queue",

initialize: function () {
}
});

Backbone.View.prototype.close = function () {
this.remove();
this.unbind();
if (this.onClose) {
    this.onClose();
}
}

And this is my main view to bind socket.io event in searchResultItemview.

var MainView = Backbone.View.extend({
initialize: function () {
    this.__initialize();
},

__initialize: function () {
    if (this.socket_events && _.size(this.socket_events) > 0) {
        this.delegateSocketEvents(this.socket_events);
    }
},

delegateSocketEvents: function (events) {

    for (var key in events) {
        var method = events[key];
        if (!_.isFunction(method)) {
            method = this[events[key]];
        }

        if (!method) {
            throw new Error('Method "' + events[key] + '" does not exist');
        }

        method = _.bind(method, this);
        socket.on(key, method);
    };
}
});

For extra information:

1. I am opening socket connection globally. Like this :
   var socket = io.connect('http://localhost:3000');

I am waiting for any kind of advice or solution to get out of this problem. Please feel free to ask any kind of inquiries.


Basically you have to do socket.removeListener for every socket.on when you close your View.

You can update your MainView and add a close method.

This is how it looks in my code (CoffeeScript)

close: ->
    self = @
    _.each @socket_events, (method, key) ->
        method = self[self.socket_events[key]]
        socket.removeListener key, method
链接地址: http://www.djcxy.com/p/63102.html

上一篇: 改变model.save()事件在主干中发射两次

下一篇: 如何从我的骨干视图中解除所有socket.io事件?