在使用 socket.io 开发具有实时消息的应用程序时,我还需要保存消息。我选择使用 mongodb,在客户端我使用 Backbone 。
我的问题是,当我发出新消息时,所有套接字/用户都会实时获取该消息,但发送该消息的套接字/用户会获取该消息两次,一次来自套接字,一次来自重新渲染的集合。
这是我的收藏 View 的样子。
module.exports = CollectionView = Marionette.CollectionView.extend({
className: 'collection',
initialize: function() {
//this.listenTo(this.collection, 'change', this.render);
},
itemView: MessageView
});
我注释掉了this.listenTo(this.collection, 'change', this.render);
。所以我问这个问题是因为也许 Marionette 默认渲染 CollectionView?也许有人解释了如何防止发送消息的套接字/用户被附加两次?
编辑:刚刚有了一个想法,我可以在发出新消息时获取集合,而不是附加消息?我尝试了一下,确实有效,也许还有更好的方法?我仍在思考,并对新想法持开放态度!
编辑:这对我来说效果很好。我没有附加 html,而是向所有连接的套接字发出 GET 请求,这样它们就可以获得新数据。
createMessage: function(data) {
window.App.data.messages.fetch({
success: function() {
console.log('success')
}
});
//this.$el.find('.message-content').append('<div class="message"><b>'+data.username+':</b>'+data.message+'</div>');
window.App.core.vent.trigger('app:log', 'Chat View: Received a new message!');
}
上述唯一的问题是顺序是 POST,然后是 GET,彼此之间的时间间隔在几毫秒内,因此 GET 请求可能会在 POST 完全完成之前返回数据。
所以我试图弄清楚如何设置回调,以便当 POST 成功添加到集合时进行 GET。如果我遇到了,我会分享解决方案。
最佳答案
您没有显示您的 socket.io 客户端代码,但我认为您的第二种方法更好。套接字应该只发送/接收数据。我假设您的套接字中至少有 1 个“receiveMessage”事件和 1 个“sendMessage”发射事件。
我认为你可以在客户端套接字中:
收到消息(或通知我有新消息)时,使用 Collection.add(message) 将消息添加到您的集合中。 Marionette 将为您呈现该消息。
发送消息时,只需将其添加到您的集合中,或者等待服务器的回调(请参阅文档)以确保在添加到集合之前正确接收消息。
<
如果您使用的是 Marionette View ,千万不要使用 jQuery 将某些内容附加到 View 的 HTML 中! ;)
对于初始消息加载,请首次使用 Collection.fetch() (例如,一旦连接了套接字)即可获取服务器上已有的所有消息。从那时起,添加单独的消息,而不是获取所有消息(您将节省带宽)。
我在类似的应用程序中所做的就是在第一次连接时从套接字发送一条“Hello”消息,其中包括我需要的数据。然后我只需对从套接字发送的内容执行 Collection.reset(data) 即可,然后就可以开始了。您的套接字将初始化您的集合,并一次更新一条消息。
希望对你有帮助!
关于javascript - 不要在更改时渲染主干 Marionette Collection View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22676996/