背景
我有一个带有网格的 asp.net webform,当用户更新该网格中的文本框时,onchange 事件会启动一个 WebMethod 调用并更新其余更改的行。那时没有保存任何内容——我们只是在更新 UI。
要提交更改,请单击保存按钮。
这实际上在几乎所有情况下都可靠地工作。然而,有一个非常顽固的问题感觉我应该能够解决,但现在是时候请专家了。
问题场景
我正在使用 jQuery 来捕获回车键,不幸的是该事件首先触发,导致页面在回调完成之前提交。该行未正确更新。保存陈旧和令人眼花缭乱的数据。
更新
我不认为您可以使输入行为取决于回调,因为您可以在不更改行的情况下保存。在这种情况下,如果您不更改行,它将永远不会保存。
现在,如果有某种方法可以检查 javascript 的内部待办事项列表,或者创建我自己的然后以某种方式管理它,那将起作用。但这对于应该很容易的事情来说是一些繁重的工作。因此,除非专家告诉我其他情况,否则我必须假设这是错误的。
尝试
现在我正在使用内置的 jQuery 事件,并且我有这个精心设计的 setTimeout 坚持尝试保存的事实,暂停足够长的时间以至少调用 WebMethod,并依靠回调进行提交. 但事实证明 javascript ansychrony 并没有按我希望的方式工作,并且 onchange 事件甚至不会触发,直到该代码块完成。这很令人惊讶。
我在想我可以使用我自己的小对象以正确的顺序排列这些事件,并找到一种聪明的方法来触发它,等等。
这一切似乎都是错误的方向。这肯定是疯狂的矫枉过正,这是一个常见问题,我忽略了一个简单的解决方案,因为我不在 javascript 24/7 中工作。
正确的?
代码
这就是我这一分钟做对的事情。这显然是行不通的——我试图利用 jquery 的异步特性,但所有这一切显然必须在行的 onchange 事件触发之前结束:
$(document).bind("keypress", function (e) {
if (e.keyCode == 13) {
handleEnter();
return false; //apparently I should be using e.preventDefault() here.
}
});
function handleEnter() {
setTimeout(function () {
if (recalculatingRow) { //recalculatingRow is a bit managed by the onchange code.
alert('recalculating...');
return true; //recur
}
//$('input[id$="ButtonSave"]').click();
alert('no longer recalculating. click!');
return false;
}, 1000);
}
然后一个典型的行看起来像这样。请注意,我没有使用 jquery 来绑定它:
<input name="ctl00$MainContent$GridOrderItems$ctl02$TextOrderItemDose" type="text" value="200.00" maxlength="7" id="ctl00_MainContent_GridOrderItems_ctl02_TextOrderItemDose" onchange="recalculateOrderItemRow(this);" style="width:50px;" />
我可以发布 recalculateOrderItemRow 的代码,但它真的很长,现在的问题是它不会触发,直到 after keypress 事件结束。
更新 Dos 根据Nick Fitzgerald的说法(这是一篇很酷的文章),使用 setTimeout 应该会导致它变为异步。进一步挖掘 setTimeout 和 jQuery 之间的交互,以及普通 javascript 事件和 jQuery 事件之间的交互。