使用多个浏览器选项卡/窗口的backbone.js和本地存储会覆盖数据

时间:2012-06-07 07:27:18

标签: javascript backbone.js local-storage

关于在LocalStorage中使用Backbone.js的一个非常简短的问题:

我在LocalStorage中存储了一系列内容(Backbone集合)。当我的网站在多个浏览器窗口/标签中打开,并且两个窗口中的用户都向列表中添加了一些内容时,一个窗口的更改将覆盖在另一个窗口中所做的更改。

如果您想亲自尝试,只需使用示例Backbone.js Todo app:

  1. 在两个浏览器标签中打开http://backbonejs.org/examples/todos/index.html
  2. 在第一个标签中添加项'item1',在第二个标签中添加'item2'
  3. 刷新两个标签:'item1'将消失,您将只剩下'item2'
  4. 有任何建议如何防止这种情况发生,有任何标准方法可以解决这个问题吗?

    Thxx

3 个答案:

答案 0 :(得分:4)

问题是众所周知的并发丢失更新问题,请参阅Lost update in Concurrency control?。 只是为了您的理解,我可能会提出以下快速而肮脏的修复方法,提交backbone-localstorage.jsStore.prototype.save

save: function() {
    // reread data right before writing
    var store = localStorage.getItem(this.name);
    var data = (store && JSON.parse(store)) || {};
    // we may choose what is overwritten with what here
    _.extend(this.data, data);

    localStorage.setItem(this.name, JSON.stringify(this.data));
}

对于latest Github version of Backbone localStorage,我认为这应该是这样的:

save: function() {
  var store = this.localStorage().getItem(this.name);
  var records = (store && store.split(",")) || [];
  var all = _.union(records, this.records);
  this.localStorage().setItem(this.name, all.join(","));
}

答案 1 :(得分:2)

您可能希望使用sessionStorage。 请参阅http://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage

答案 2 :(得分:2)

雅罗斯拉夫关于在坚持更新之前检查变更的评论是一种解决方案,但我的建议会有所不同。请记住,localStorage能够在执行更改其保存的数据的操作时触发事件。绑定到这些事件并让每个选项卡监听这些更改并在事件发生后查看重新呈现。

然后,当我在一个标签中进行删除或添加并转到下一个标签时,它将获得一个事件并进行更改以反映其他标签中发生的事情。我所看到的标签与标签之间不会有奇怪的差异。

您需要考虑确保我不会丢失我正在添加的内容(比如我开始为我的待办事项列表键入新条目),切换到另一个标签并删除某些内容,然后回来我想看到该条目消失,但我的部分打印的新项目仍然可供我使用。