在字段编辑期间关闭反应性

Turning off Reactivity during field edit

我正在处理一个响应式表单,需要解决一个问题。问题是我的用户使用 tablets/cellphones 的手机连接速度较慢,有时甚至连接松动。重新建立连接后,Meteor 将触发所有 DDP 消息,从而触发表单中的 Reactivity,从而覆盖用户已执行但未保存的任何表单输入。

所以我想到了将临时值保存在文档中的想法,这样当用户更改表单输入时,更改将存储在 "temp" 值中,直到他们点击保存,此时我只是将临时值复制到实际值并将其清空。显示时我只是检查是否有临时值,如果有则显示,如果没有则显示原始保存的值。

这对于非文本字段(如单选按钮和复选框)非常有效,但对于文本输入则效果不佳。

问题似乎与反应性有关。当用户键入时,我在 changekeydown 上设置了一个偶数处理程序(我也尝试过 keypresskeyup),它只是触发对临时值的更新,例如这个:

'change .responseInput, keydown .responseInput': function(event, tmpl) {
  var response = Blaze.getData(tmpl.$('.headerDiv')[0]);
  var val = response.lastResponseValue;
  if (!val) {
    val = new ResponseValue({
      response_id: response.id
    });
  }
  val.tempValues = getSelectedValues(tmpl.$('div.responseDiv'));
  val.save();
}

在此事件处理程序中,response.lastResponseValue 只是 returns 最后一个响应值(我维护用户输入值的历史记录)并且 getSelectedValues() 接受一个 DOM 元素代表表单控件周围的 DIV 并删除选定的值,这些值可能是 textbox/textarea 的单个字符串,或者复选框的字符串值数组。这些作品按预期工作。

不起作用的是 val.save()。选择文本输入字段并快速键入时,体验是键入的文本是随机的 skipped/ignored/removed,很可能是由于反应性。我尝试将事件处理程序包装在 Tracker.nonreactive() 中以关闭反应性,但这似乎没有帮助。我猜是因为它不是反应性的 save(),而是 find().

我考虑过将临时值的内容分离到一个单独的文档中。然后实际值不会被触及,只有临时值附加到它,但我最终需要编写仍然返回临时值的代码,否则原始问题根本无法解决,在这种情况下我我想我会回到同一条船上,用户和反应性之间存在竞争条件。

有没有办法暂时关闭 Meteor/Blaze 中文档的反应性?或者是否有更好的 method/pattern 我可以遵循它可以使这项工作更好?

您的表单元素根本不应连接到任何反应值,否则它们将像您看到的那样被清除,并且在热代码推送期间也是如此。

相反,您应该在呈现模板时只初始化一次表单。如果在用户编辑表单时基础值发生变化,则表单不会自动更新,这在大多数用例中都是合乎逻辑的。

您仍然需要在用户进行更改时更新本地存储,以便在发生热代码推送时您可以将表单恢复到 已编辑 状态.

看看这个,它可以轻松处理所有问题:

http://viewmodel.meteor.com/

蒂姆