backbone.js - 如何从我的主干 View 中取消绑定(bind)所有 socket.io 事件?

标签 backbone.js socket.io backbone-views backbone-events

我有一个页面,其中包含两个主干 View (与两个模板相关的 View )。我正在根据另一个 View 上不同项目的单击事件更改一个 View 的内容。为此,每次我单击一个 View 中的任何项目时,我只是创建另一个 View 的实例,其中包含一些 socket.io 事件。第一次它运行良好,但每次我在第一个 View 中单击项目时,它只会创建第二个实例,以便绑定(bind)所有 socket.io 事件。除了每次我点击第一个 View 上的项目并调用 socket.io 事件时第一次点击外,它会根据我对不同项目所做的点击次数触发不止一次。

我知道每次我单击一个项目时,它都会创建一个带有 socket.io 事件绑定(bind)的 View 实例。但是我无法获得解除绑定(bind)以前的 socket.io 事件的方法。

我尝试使用这个引用: Backbone.js View removing and unbinding 但这对我来说不起作用。可能是我没有以正确的方式使用它。

任何人都可以给我一个解决方案或方法来解除绑定(bind)之前绑定(bind)的所有 socket.io 事件吗?

这是我的 Clicking 事件,我从这里创建另一个 View 的新实例,所有 socket.io 事件都绑定(bind)在该 View 中。

 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');
        }
    });
   }

这是我绑定(bind)所有 socket.io 事件的实际 View 。

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();
}
}

这是我在 searchResultItemview 中绑定(bind) socket.io 事件的主要 View 。

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);
    };
}
});

额外信息:

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

我正在等待任何类型的建议或解决方案来解决这个问题。如有任何疑问,请随时提出。

最佳答案

基本上,当您关闭 View 时,您必须为每个 socket.on 执行 socket.removeListener

您可以更新您的 MainView 并添加一个 close 方法。

这是它在我的代码 (CoffeeScript) 中的样子

close: ->
    self = @
    _.each @socket_events, (method, key) ->
        method = self[self.socket_events[key]]
        socket.removeListener key, method

关于backbone.js - 如何从我的主干 View 中取消绑定(bind)所有 socket.io 事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15195412/

相关文章:

javascript - 清除主干模型上除一个属性外的所有属性

node.js - html页面刷新后如何避免在socket.io中创建新的套接字连接?

javascript - BackboneJs 应用程序不渲染任何内容

javascript - backbone.js "order"属性像 TodoMVC 不递增

javascript - 如何只调用一次 Backbone View 事件?

javascript - 如何在 Backbone.js View 中触发/绑定(bind)自定义事件?

templates - 使用模板进行 Jasmine 测试

javascript - Nodejs 和套接字 io 错误 : listen EADDRINUSE

javascript - 如果我需要保存 Backbone.Collection,这是代码味道吗?

Mysql 更改 Node.js 的监听器