代码之家  ›  专栏  ›  技术社区  ›  CodeChimp

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

  •  0
  • CodeChimp  · 技术社区  · 10 年前

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

    因此,我想到了将临时值保存在文档中的想法,这样当用户更改表单输入时,更改将存储在“临时”值中,直到它们单击“保存”,此时我只需将临时值复制到实际值并将其留空。在显示时,我只需检查是否有临时值,如果有,则显示该值,如果没有,则显示原始保存的值。

    这对于非文本字段(如单选按钮和复选框)非常有用,但对于文本输入来说,它根本不起作用。

    问题似乎在于反应性。当用户输入时,我设置了一个偶数处理程序 change keydown (我也试过 keypress keyup )它只需对temp值进行如下更新:

    '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,但我最终需要编写仍然返回temp值的代码,否则原始问题根本无法解决,在这种情况下,我想我会回到用户和反应性之间存在竞争条件的同一条船上。

    有没有办法暂时关闭Meteor/Blaze中文档的反应性?或者有没有一种更好的方法/模式可以让我更好地工作?

    1 回复  |  直到 10 年前
        1
  •  0
  •   tarmes    10 年前

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

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

    但是,当用户进行更改时,您仍然需要更新本地存储,这样您就可以将表单放回 已编辑 如果发生热代码推送,请说明。

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

    http://viewmodel.meteor.com/

    提姆