2

2つのバックボーンビュー(2つのテンプレートに関連するビュー)を含むページがあります。別のビューのさまざまなアイテムのクリックイベントに基づいて、1つのビューのコンテンツを変更しています。このため、あるビューのアイテムをクリックするたびに、socket.ioイベントを含む別のビューのインスタンスを作成します。最初はうまく機能しますが、最初のビューでアイテムをクリックするたびに、2番目のインスタンスが作成されるため、すべてのsocket.ioイベントがバインドされます。最初のビューでアイテムをクリックしてsocket.ioイベントを呼び出すたびに最初のクリックを行うことを除いて、さまざまなアイテムに対して行ったクリック数に基づいて、複数回発生しました。

アイテムをクリックするたびに、socket.ioイベントバインドを使用してビューのインスタンスが作成されることを知っています。しかし、以前のsocket.ioイベントのバインドを解除する方法を取得できません。

私はこの参照を使用しようとしました: Backbone.jsビューの削除とバインド解除 しかし、私の場合は機能していません。私はそれを適切な方法で使用しなかったのかもしれません。

以前にバインドされたすべてのsocket.ioイベントのバインドを解除するための解決策または方法を教えてもらえますか?

これが私のClickingイベントで、すべてのsocket.ioイベントがバインドされる別のビューの新しいインスタンスを作成しています。

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

そして、これがすべてのsocket.ioイベントをバインドする実際のビューです。

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でsocket.ioイベントをバインドするためのメインビューです。

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

私はこの問題から抜け出すためのあらゆる種類のアドバイスや解決策を待っています。お気軽にお問い合わせください。

4

1 に答える 1

2

基本的に、ビューを閉じるsocket.removeListenerたびに行う必要があります。socket.on

MainView を更新してcloseメソッドを追加できます。

これは私のコード(CoffeeScript)でどのように見えるかです

close: ->
    self = @
    _.each @socket_events, (method, key) ->
        method = self[self.socket_events[key]]
        socket.removeListener key, method
于 2013-04-10T11:01:19.273 に答える