【问题标题】:Turning off Reactivity during field edit在字段编辑期间关闭反应性
【发布时间】:2015-03-10 19:52:44
【问题描述】:

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

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

这对于单选按钮和复选框等非文本字段非常有效,但对于文本输入则完全不适用。

问题似乎与反应性有关。当用户输入时,我在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 只返回最后一个响应值(我维护用户输入值的历史记录),getSelectedValues() 采用代表表单控件周围 DIV 的 DOM 元素并刮掉选定的值,这可能是文本框/文本区域的单个字符串,或者复选框的字符串值数组。这些部件按预期工作。

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

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

有没有办法暂时关闭 Meteor/Blaze 中文档的响应性?或者是否有更好的方法/模式可以让我更好地完成这项工作?

【问题讨论】:

    标签: meteor meteor-blaze


    【解决方案1】:

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

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

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

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

    http://viewmodel.meteor.com/

    提姆

    【讨论】:

    • 所以,我一直在阅读 ViewModel。我认为这正是我所需要的。我在交换它时遇到的一个问题是,当值可以是一组项目时,我还没有找到一种处理绑定的方法,比如当你有一堆复选框时。他们的复选框绑定示例假设每个复选框都有一个 VM。
    • 我错过了将多个复选框绑定到数组的情况。我将更新 ViewModel。这很容易解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 2020-06-22
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多