【发布时间】:2015-03-30 15:19:11
【问题描述】:
我正在尝试制作一个允许多人同时编辑正文的 Meteor 应用程序(想想 Google Docs/Drive)。
我想为了做到这一点,我需要一个模板来显示当前数据库中的文本,然后每当修改文本时,它都需要更新数据库中的文本。
我能够在下面的这个最小复制中从我的完整应用程序中重现相同的问题(设计为由单个用户而不是多个用户使用,因此从使用 Mongo 集合交换为会话。)
<body>
{{> hello}}
</body>
<template name="hello">
<pre contentEditable="true">{{text}}</pre>
</template>
(如果我使用div 而不是pre,则会出现完全相同的问题。)
if (Meteor.isClient) {
Session.setDefault('text', "Edit me!");
Template.hello.helpers({
text: function () {
return Session.get('text');
}
});
Template.hello.events({
"input pre": function (event) {
Session.set('text', $(event.target).text());
}
});
}
尝试在应用程序中输入一些内容,您很快就会发现该错误:每次击键时,它都会获取所有现有文本并将其附加到您输入的内容(因此每次击键时,它都会复制所有文本)。这是真正奇怪的部分:这种行为并不总是立即开始......事实上,我还没有找到任何特别可靠的重现它的方法。一旦它复制了一次文本,它就会在每次击键时可靠地一次又一次地重复,直到您刷新页面为止。刷新页面后,有时该错误会在您下一次击键时再次出现,有时可能需要大约 20 次击键才会出现。
我已经在 Safari 8(OS X 和 iOS)、Chrome(OS X 和 Windows)和 Firefox(仅 OS X)上对此进行了测试,并且问题出现在每个浏览器中。
如果您还不能重现它,请尝试突出显示所有文本、删除它并输入。也尝试开始一个新行。我发现这些操作似乎更有可能引发文本重复,但即使是那些也不会始终如一地引发问题。
我的问题是:
- 为什么会出现这个错误?
- 我怎样才能阻止它发生?
如果您想直接查看问题而不必运行流星服务器(尽管我已经为您提供了所有代码......)我把它扔了here。
【问题讨论】:
-
抱歉,您将无法使用 Session 进行多用户编辑,因为它仅在浏览器客户端中可用(并且也不会像 cookie 那样持续存在,因此当您刷新时它就消失了) .您需要使用 Collection 以便所有用户都可以检索内容。
-
@IanJones:请参阅我的问题的第 3 段,我解释说我能够使用 Sessions 而不是 Collections 重现我的特定问题。我这样做是为了尽量减少需要共享的代码量(当你试图找出问题的根本原因时,尽量减少问题的重现也是一个好主意。)
-
对不起,我误解了......我现在明白了你的意思是使用 Session 只是为了举例。 'input pre' 究竟是一个事件?对我来说,这似乎不是一种事件类型。
标签: javascript meteor spacebars