【发布时间】:2015-03-10 19:52:44
【问题描述】:
我正在处理一个响应式表单,需要解决一个问题。问题是我的用户使用平板电脑/手机的手机连接速度较慢,有时连接松动。当重新建立连接时,Meteor 将触发所有 DDP 消息,从而触发表单中的 Reactivity,从而覆盖用户已执行但未保存的任何表单输入。
所以我想出了将临时值保存在文档中的想法,这样当用户更改表单输入时,更改将存储在“临时”值中,直到他们点击保存,此时我只需复制将温度值转换为实际值并将其空白。显示时我只是检查是否有临时值,如果有则显示,如果没有则显示原始保存的值。
这对于单选按钮和复选框等非文本字段非常有效,但对于文本输入则完全不适用。
问题似乎与反应性有关。当用户输入时,我在change 和keydown 上设置了一个偶数处理程序(我也尝试了keypress 和keyup),它只是触发对临时值的更新,如下所示:
'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